diff --git a/Evernote-SDK-iOS.podspec b/Evernote-SDK-iOS.podspec index f52f88c..5a6d35f 100644 --- a/Evernote-SDK-iOS.podspec +++ b/Evernote-SDK-iOS.podspec @@ -15,5 +15,5 @@ Pod::Spec.new do |s| s.libraries = 'xml2' s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"$(SDKROOT)/usr/include/libxml2"' } - s.dependency 'SSKeychain', '0.2.1' + s.dependency 'SAMKeychain', '~>1.5.0' end diff --git a/evernote-sdk-ios.xcodeproj/project.pbxproj b/evernote-sdk-ios.xcodeproj/project.pbxproj index b338de0..fa0229a 100755 --- a/evernote-sdk-ios.xcodeproj/project.pbxproj +++ b/evernote-sdk-ios.xcodeproj/project.pbxproj @@ -102,11 +102,14 @@ 0BDBBC5A1550A1E7003E6681 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BF0CF84152E2601003D6115 /* Security.framework */; }; 0BDBBC671550A3A4003E6681 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDBBC5E1550A3A4003E6681 /* libOCMock.a */; }; 0BDBBC681550A3A4003E6681 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 0BDBBC5F1550A3A4003E6681 /* LICENSE */; }; - 0BF0CF81152E25E1003D6115 /* SSKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BF0CF7F152E25E1003D6115 /* SSKeychain.h */; }; - 0BF0CF82152E25E1003D6115 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BF0CF80152E25E1003D6115 /* SSKeychain.m */; }; 0BF0CF85152E2601003D6115 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BF0CF84152E2601003D6115 /* Security.framework */; }; - 0BF0CF8A152E31BA003D6115 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BF0CF80152E25E1003D6115 /* SSKeychain.m */; }; 0BF0CF8C152E31CC003D6115 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BF0CF84152E2601003D6115 /* Security.framework */; }; + 6FF9DA481D787BD100F4BC7F /* SAMKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FF9DA441D787BD100F4BC7F /* SAMKeychain.h */; }; + 6FF9DA491D787BD100F4BC7F /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FF9DA451D787BD100F4BC7F /* SAMKeychain.m */; }; + 6FF9DA4A1D787BD100F4BC7F /* SAMKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FF9DA451D787BD100F4BC7F /* SAMKeychain.m */; }; + 6FF9DA4B1D787BD100F4BC7F /* SAMKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FF9DA461D787BD100F4BC7F /* SAMKeychainQuery.h */; }; + 6FF9DA4C1D787BD100F4BC7F /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FF9DA471D787BD100F4BC7F /* SAMKeychainQuery.m */; }; + 6FF9DA4D1D787BD100F4BC7F /* SAMKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FF9DA471D787BD100F4BC7F /* SAMKeychainQuery.m */; }; A90C479917CBC2A6007DDD61 /* index.php in CopyFiles */ = {isa = PBXBuildFile; fileRef = A99B6E7F17CBC20D00A51A1B /* index.php */; }; A90C479A17CBC2A6007DDD61 /* evernote-export.dtd in CopyFiles */ = {isa = PBXBuildFile; fileRef = A99B6E8017CBC20D00A51A1B /* evernote-export.dtd */; }; A90C479B17CBC2A6007DDD61 /* promotions.dtd in CopyFiles */ = {isa = PBXBuildFile; fileRef = A99B6E8117CBC20D00A51A1B /* promotions.dtd */; }; @@ -358,11 +361,13 @@ 0BDBBC641550A3A4003E6681 /* OCMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMock.h; sourceTree = ""; }; 0BDBBC651550A3A4003E6681 /* OCMockObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMockObject.h; sourceTree = ""; }; 0BDBBC661550A3A4003E6681 /* OCMockRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMockRecorder.h; sourceTree = ""; }; - 0BF0CF7E152E25E1003D6115 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 0BF0CF7F152E25E1003D6115 /* SSKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKeychain.h; sourceTree = ""; }; - 0BF0CF80152E25E1003D6115 /* SSKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSKeychain.m; sourceTree = ""; }; 0BF0CF84152E2601003D6115 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 0BF0CF93152E53E0003D6115 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + 6FF9DA431D787BC400F4BC7F /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE; path = "evernote-sdk-ios/3rdParty/SAMKeychain/LICENSE"; sourceTree = SOURCE_ROOT; }; + 6FF9DA441D787BD100F4BC7F /* SAMKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SAMKeychain.h; path = "evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.h"; sourceTree = SOURCE_ROOT; }; + 6FF9DA451D787BD100F4BC7F /* SAMKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SAMKeychain.m; path = "evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.m"; sourceTree = SOURCE_ROOT; }; + 6FF9DA461D787BD100F4BC7F /* SAMKeychainQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SAMKeychainQuery.h; path = "evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.h"; sourceTree = SOURCE_ROOT; }; + 6FF9DA471D787BD100F4BC7F /* SAMKeychainQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SAMKeychainQuery.m; path = "evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.m"; sourceTree = SOURCE_ROOT; }; A92602BB1672B4FE00F01E63 /* evernote_logo_4c-sm.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "evernote_logo_4c-sm.png"; sourceTree = ""; }; A92602BD1672B6DD00F01E63 /* NSData+EvernoteSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+EvernoteSDK.h"; sourceTree = ""; }; A92602BE1672B6DD00F01E63 /* NSData+EvernoteSDK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+EvernoteSDK.m"; sourceTree = ""; }; @@ -512,7 +517,7 @@ A96FE4EB16A0A3DB00F1AD8C /* AFNetworking */, 0B943F251525015500DB20A3 /* cocoa-oauth */, 0B943F2B1525015500DB20A3 /* NSString+URLEncoding */, - 0BF0CF7D152E25E1003D6115 /* SSKeychain */, + 0BF0CF7D152E25E1003D6115 /* SAMKeychain */, 0B943F2E1525015500DB20A3 /* Thrift */, ); path = 3rdParty; @@ -789,13 +794,16 @@ path = OCMock; sourceTree = ""; }; - 0BF0CF7D152E25E1003D6115 /* SSKeychain */ = { + 0BF0CF7D152E25E1003D6115 /* SAMKeychain */ = { isa = PBXGroup; children = ( - 0BF0CF7E152E25E1003D6115 /* LICENSE */, - 0BF0CF7F152E25E1003D6115 /* SSKeychain.h */, - 0BF0CF80152E25E1003D6115 /* SSKeychain.m */, + 6FF9DA431D787BC400F4BC7F /* LICENSE */, + 6FF9DA441D787BD100F4BC7F /* SAMKeychain.h */, + 6FF9DA451D787BD100F4BC7F /* SAMKeychain.m */, + 6FF9DA461D787BD100F4BC7F /* SAMKeychainQuery.h */, + 6FF9DA471D787BD100F4BC7F /* SAMKeychainQuery.m */, ); + name = SAMKeychain; path = SSKeychain; sourceTree = ""; }; @@ -982,6 +990,7 @@ 0B943F601525015500DB20A3 /* TProtocolException.h in Headers */, 0B943F631525015500DB20A3 /* TProtocolFactory.h in Headers */, 0B943F641525015500DB20A3 /* TProtocolUtil.h in Headers */, + 6FF9DA481D787BD100F4BC7F /* SAMKeychain.h in Headers */, 0B943F6A1525015500DB20A3 /* TApplicationException.h in Headers */, 0B943F6D1525015500DB20A3 /* TException.h in Headers */, 0B943F711525015500DB20A3 /* TProcessor.h in Headers */, @@ -1005,6 +1014,7 @@ A9C554FC16712F17006E0020 /* NSDate+EDAMAdditions.h in Headers */, A96FE4D816A0958600F1AD8C /* EDAMNoteStoreClient+Utilities.h in Headers */, 0B943F591525015500DB20A3 /* NSString+URLEncoding.h in Headers */, + 6FF9DA4B1D787BD100F4BC7F /* SAMKeychainQuery.h in Headers */, A92602C416740D5700F01E63 /* ENMLUtility.h in Headers */, A92602BF1672B6DD00F01E63 /* NSData+EvernoteSDK.h in Headers */, 0B2B9D621544944800E5BD44 /* EvernoteUserStore.h in Headers */, @@ -1012,7 +1022,6 @@ 0B943F831525015500DB20A3 /* TTransportException.h in Headers */, 0B943F521525015500DB20A3 /* ENGCOAuth.h in Headers */, 0B943F551525015500DB20A3 /* NSData+ENBase64.h in Headers */, - 0BF0CF81152E25E1003D6115 /* SSKeychain.h in Headers */, 0B98592815432592007D7D37 /* ENAPI.h in Headers */, 0B98592B15432592007D7D37 /* ENCredentials.h in Headers */, 0B98592E15432592007D7D37 /* ENCredentialStore.h in Headers */, @@ -1204,8 +1213,10 @@ 0BB3D2401524EE62001C4534 /* EDAMTypes.m in Sources */, 0BB3D2421524EE62001C4534 /* EDAMUserStore.m in Sources */, 0BB3D2441524EE62001C4534 /* EDAMErrors.m in Sources */, + 6FF9DA491D787BD100F4BC7F /* SAMKeychain.m in Sources */, 0BB3D2461524EE62001C4534 /* EvernoteSession.m in Sources */, 0B943F531525015500DB20A3 /* ENGCOAuth.m in Sources */, + 6FF9DA4C1D787BD100F4BC7F /* SAMKeychainQuery.m in Sources */, 0B943F561525015500DB20A3 /* NSData+ENBase64.m in Sources */, 0B943F5A1525015500DB20A3 /* NSString+URLEncoding.m in Sources */, 0B943F5D1525015500DB20A3 /* TBinaryProtocol.m in Sources */, @@ -1216,7 +1227,6 @@ 0B943F741525015500DB20A3 /* THTTPClient.m in Sources */, 0B943F771525015500DB20A3 /* TMemoryBuffer.m in Sources */, 0B943F841525015500DB20A3 /* TTransportException.m in Sources */, - 0BF0CF82152E25E1003D6115 /* SSKeychain.m in Sources */, 0B98592915432592007D7D37 /* ENAPI.m in Sources */, 0B98592C15432592007D7D37 /* ENCredentials.m in Sources */, 0B98592F15432592007D7D37 /* ENCredentialStore.m in Sources */, @@ -1268,8 +1278,10 @@ 0BB3D2921524F01E001C4534 /* EDAMUserStore.m in Sources */, 0BB3D2931524F01E001C4534 /* EDAMErrors.m in Sources */, 0BB3D27A1524EF37001C4534 /* main.m in Sources */, + 6FF9DA4A1D787BD100F4BC7F /* SAMKeychain.m in Sources */, 0BB3D27E1524EF37001C4534 /* AppDelegate.m in Sources */, 0BB3D2841524EF37001C4534 /* ENRootViewController.m in Sources */, + 6FF9DA4D1D787BD100F4BC7F /* SAMKeychainQuery.m in Sources */, 0B943F541525015500DB20A3 /* ENGCOAuth.m in Sources */, 0B943F571525015500DB20A3 /* NSData+ENBase64.m in Sources */, 0B943F5B1525015500DB20A3 /* NSString+URLEncoding.m in Sources */, @@ -1281,7 +1293,6 @@ 0B943F751525015500DB20A3 /* THTTPClient.m in Sources */, 0B943F781525015500DB20A3 /* TMemoryBuffer.m in Sources */, 0B943F851525015500DB20A3 /* TTransportException.m in Sources */, - 0BF0CF8A152E31BA003D6115 /* SSKeychain.m in Sources */, 0B98592A15432592007D7D37 /* ENAPI.m in Sources */, 0B98592D15432592007D7D37 /* ENCredentials.m in Sources */, 0B98593015432592007D7D37 /* ENCredentialStore.m in Sources */, diff --git a/evernote-sdk-ios/3rdParty/SSKeychain/LICENSE b/evernote-sdk-ios/3rdParty/SAMKeychain/LICENSE old mode 100755 new mode 100644 similarity index 95% rename from evernote-sdk-ios/3rdParty/SSKeychain/LICENSE rename to evernote-sdk-ios/3rdParty/SAMKeychain/LICENSE index ab23a91..21fe4ef --- a/evernote-sdk-ios/3rdParty/SSKeychain/LICENSE +++ b/evernote-sdk-ios/3rdParty/SAMKeychain/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2010-2011 Sam Soffes. +Copyright (c) 2010-2016 Sam Soffes, http://soff.es Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.h b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.h new file mode 100644 index 0000000..dcff6a4 --- /dev/null +++ b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.h @@ -0,0 +1,197 @@ +// +// SAMKeychain.h +// SAMKeychain +// +// Created by Sam Soffes on 5/19/10. +// Copyright (c) 2010-2014 Sam Soffes. All rights reserved. +// + +#if __has_feature(modules) + @import Foundation; +#else + #import +#endif + +/** + Error code specific to SAMKeychain that can be returned in NSError objects. + For codes returned by the operating system, refer to SecBase.h for your + platform. + */ +typedef NS_ENUM(OSStatus, SAMKeychainErrorCode) { + /** Some of the arguments were invalid. */ + SAMKeychainErrorBadArguments = -1001, +}; + +/** SAMKeychain error domain */ +extern NSString *const kSAMKeychainErrorDomain; + +/** Account name. */ +extern NSString *const kSAMKeychainAccountKey; + +/** + Time the item was created. + + The value will be a string. + */ +extern NSString *const kSAMKeychainCreatedAtKey; + +/** Item class. */ +extern NSString *const kSAMKeychainClassKey; + +/** Item description. */ +extern NSString *const kSAMKeychainDescriptionKey; + +/** Item label. */ +extern NSString *const kSAMKeychainLabelKey; + +/** Time the item was last modified. + + The value will be a string. + */ +extern NSString *const kSAMKeychainLastModifiedKey; + +/** Where the item was created. */ +extern NSString *const kSAMKeychainWhereKey; + +/** + 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. + SAMKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it). + */ +@interface SAMKeychain : NSObject + +#pragma mark - Classic methods + +/** + 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. + */ ++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; ++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); + +/** + Returns a nsdata 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 nsdata containing the password for a given account and service, or `nil` if the Keychain doesn't + have a password for the given parameters. + */ ++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; ++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); + + +/** + 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. + */ ++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; ++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); + + +/** + 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. + */ ++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; ++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); + +/** + 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. + */ ++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; ++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error __attribute__((swift_error(none))); + +/** + Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts. + + See the `NSString` constants declared in SAMKeychain.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. + */ ++ (NSArray *> *)allAccounts; ++ (NSArray *> *)allAccounts:(NSError *__autoreleasing *)error __attribute__((swift_error(none))); + + +/** + 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 SAMKeychain.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 accounts for 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. + */ ++ (NSArray *> *)accountsForService:(NSString *)serviceName; ++ (NSArray *> *)accountsForService:(NSString *)serviceName error:(NSError *__autoreleasing *)error __attribute__((swift_error(none))); + + +#pragma mark - 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 setAccessibilityType + */ ++ (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 which + is highly insecure. You really should use at least `kSecAttrAccessibleAfterFirstUnlock` + for background applications or `kSecAttrAccessibleWhenUnlocked` for all + other applications. + + @see accessibilityType + */ ++ (void)setAccessibilityType:(CFTypeRef)accessibilityType; +#endif + +@end diff --git a/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.m b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.m new file mode 100644 index 0000000..9ba73be --- /dev/null +++ b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychain.m @@ -0,0 +1,130 @@ +// +// SAMKeychain.m +// SAMKeychain +// +// Created by Sam Soffes on 5/19/10. +// Copyright (c) 2010-2014 Sam Soffes. All rights reserved. +// + +#import "SAMKeychain.h" +#import "SAMKeychainQuery.h" + +NSString *const kSAMKeychainErrorDomain = @"com.samsoffes.samkeychain"; +NSString *const kSAMKeychainAccountKey = @"acct"; +NSString *const kSAMKeychainCreatedAtKey = @"cdat"; +NSString *const kSAMKeychainClassKey = @"labl"; +NSString *const kSAMKeychainDescriptionKey = @"desc"; +NSString *const kSAMKeychainLabelKey = @"labl"; +NSString *const kSAMKeychainLastModifiedKey = @"mdat"; +NSString *const kSAMKeychainWhereKey = @"svce"; + +#if __IPHONE_4_0 && TARGET_OS_IPHONE + static CFTypeRef SAMKeychainAccessibilityType = NULL; +#endif + +@implementation SAMKeychain + ++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account { + return [self passwordForService:serviceName account:account error:nil]; +} + + ++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + query.account = account; + [query fetch:error]; + return query.password; +} + ++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account { + return [self passwordDataForService:serviceName account:account error:nil]; +} + ++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + query.account = account; + [query fetch:error]; + + return query.passwordData; +} + + ++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account { + return [self deletePasswordForService:serviceName account:account error:nil]; +} + + ++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + query.account = account; + return [query deleteItem:error]; +} + + ++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account { + return [self setPassword:password forService:serviceName account:account error:nil]; +} + + ++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + query.account = account; + query.password = password; + return [query save:error]; +} + ++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account { + return [self setPasswordData:password forService:serviceName account:account error:nil]; +} + + ++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + query.account = account; + query.passwordData = password; + return [query save:error]; +} + ++ (NSArray *)allAccounts { + return [self allAccounts:nil]; +} + + ++ (NSArray *)allAccounts:(NSError *__autoreleasing *)error { + return [self accountsForService:nil error:error]; +} + + ++ (NSArray *)accountsForService:(NSString *)serviceName { + return [self accountsForService:serviceName error:nil]; +} + + ++ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError *__autoreleasing *)error { + SAMKeychainQuery *query = [[SAMKeychainQuery alloc] init]; + query.service = serviceName; + return [query fetchAll:error]; +} + + +#if __IPHONE_4_0 && TARGET_OS_IPHONE ++ (CFTypeRef)accessibilityType { + return SAMKeychainAccessibilityType; +} + + ++ (void)setAccessibilityType:(CFTypeRef)accessibilityType { + CFRetain(accessibilityType); + if (SAMKeychainAccessibilityType) { + CFRelease(SAMKeychainAccessibilityType); + } + SAMKeychainAccessibilityType = accessibilityType; +} +#endif + +@end diff --git a/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.h b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.h new file mode 100644 index 0000000..8854103 --- /dev/null +++ b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.h @@ -0,0 +1,143 @@ +// +// SAMKeychainQuery.h +// SAMKeychain +// +// Created by Caleb Davenport on 3/19/13. +// Copyright (c) 2013-2014 Sam Soffes. All rights reserved. +// + +#if __has_feature(modules) + @import Foundation; + @import Security; +#else + #import + #import +#endif + +#if __IPHONE_7_0 || __MAC_10_9 + // Keychain synchronization available at compile time + #define SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE 1 +#endif + +#if __IPHONE_3_0 || __MAC_10_9 + // Keychain access group available at compile time + #define SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE 1 +#endif + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE +typedef NS_ENUM(NSUInteger, SAMKeychainQuerySynchronizationMode) { + SAMKeychainQuerySynchronizationModeAny, + SAMKeychainQuerySynchronizationModeNo, + SAMKeychainQuerySynchronizationModeYes +}; +#endif + +/** + Simple interface for querying or modifying keychain items. + */ +@interface SAMKeychainQuery : NSObject + +/** kSecAttrAccount */ +@property (nonatomic, copy) NSString *account; + +/** kSecAttrService */ +@property (nonatomic, copy) NSString *service; + +/** kSecAttrLabel */ +@property (nonatomic, copy) NSString *label; + +#ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE +/** kSecAttrAccessGroup (only used on iOS) */ +@property (nonatomic, copy) NSString *accessGroup; +#endif + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE +/** kSecAttrSynchronizable */ +@property (nonatomic) SAMKeychainQuerySynchronizationMode synchronizationMode; +#endif + +/** Root storage for password information */ +@property (nonatomic, copy) NSData *passwordData; + +/** + This property automatically transitions between an object and the value of + `passwordData` using NSKeyedArchiver and NSKeyedUnarchiver. + */ +@property (nonatomic, copy) id passwordObject; + +/** + Convenience accessor for setting and getting a password string. Passes through + to `passwordData` using UTF-8 string encoding. + */ +@property (nonatomic, copy) NSString *password; + + +///------------------------ +/// @name Saving & Deleting +///------------------------ + +/** + Save the receiver's attributes as a keychain item. Existing items with the + given account, service, and access group will first be deleted. + + @param error Populated should an error occur. + + @return `YES` if saving was successful, `NO` otherwise. + */ +- (BOOL)save:(NSError **)error; + +/** + Delete keychain items that match the given account, service, and access group. + + @param error Populated should an error occur. + + @return `YES` if saving was successful, `NO` otherwise. + */ +- (BOOL)deleteItem:(NSError **)error; + + +///--------------- +/// @name Fetching +///--------------- + +/** + Fetch all keychain items that match the given account, service, and access + group. The values of `password` and `passwordData` are ignored when fetching. + + @param error Populated should an error occur. + + @return An array of dictionaries that represent all matching keychain items or + `nil` should an error occur. + The order of the items is not determined. + */ +- (NSArray *> *)fetchAll:(NSError **)error; + +/** + Fetch the keychain item that matches the given account, service, and access + group. The `password` and `passwordData` properties will be populated unless + an error occurs. The values of `password` and `passwordData` are ignored when + fetching. + + @param error Populated should an error occur. + + @return `YES` if fetching was successful, `NO` otherwise. + */ +- (BOOL)fetch:(NSError **)error; + + +///----------------------------- +/// @name Synchronization Status +///----------------------------- + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE +/** + Returns a boolean indicating if keychain synchronization is available on the device at runtime. The #define + SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE is only for compile time. If you are checking for the presence of synchronization, + you should use this method. + + @return A value indicating if keychain synchronization is available + */ ++ (BOOL)isSynchronizationAvailable; +#endif + +@end diff --git a/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.m b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.m new file mode 100644 index 0000000..798032d --- /dev/null +++ b/evernote-sdk-ios/3rdParty/SAMKeychain/SAMKeychainQuery.m @@ -0,0 +1,316 @@ +// +// SAMKeychainQuery.m +// SAMKeychain +// +// Created by Caleb Davenport on 3/19/13. +// Copyright (c) 2013-2014 Sam Soffes. All rights reserved. +// + +#import "SAMKeychainQuery.h" +#import "SAMKeychain.h" + +@implementation SAMKeychainQuery + +@synthesize account = _account; +@synthesize service = _service; +@synthesize label = _label; +@synthesize passwordData = _passwordData; + +#ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE +@synthesize accessGroup = _accessGroup; +#endif + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE +@synthesize synchronizationMode = _synchronizationMode; +#endif + +#pragma mark - Public + +- (BOOL)save:(NSError *__autoreleasing *)error { + OSStatus status = SAMKeychainErrorBadArguments; + if (!self.service || !self.account || !self.passwordData) { + if (error) { + *error = [[self class] errorWithCode:status]; + } + return NO; + } + NSMutableDictionary *query = nil; + NSMutableDictionary * searchQuery = [self query]; + status = SecItemCopyMatching((__bridge CFDictionaryRef)searchQuery, nil); + if (status == errSecSuccess) {//item already exists, update it! + query = [[NSMutableDictionary alloc]init]; + [query setObject:self.passwordData forKey:(__bridge id)kSecValueData]; +#if __IPHONE_4_0 && TARGET_OS_IPHONE + CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; + if (accessibilityType) { + [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; + } +#endif + status = SecItemUpdate((__bridge CFDictionaryRef)(searchQuery), (__bridge CFDictionaryRef)(query)); + }else if(status == errSecItemNotFound){//item not found, create it! + query = [self query]; + if (self.label) { + [query setObject:self.label forKey:(__bridge id)kSecAttrLabel]; + } + [query setObject:self.passwordData forKey:(__bridge id)kSecValueData]; +#if __IPHONE_4_0 && TARGET_OS_IPHONE + CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; + if (accessibilityType) { + [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; + } +#endif + status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); + } + if (status != errSecSuccess && error != NULL) { + *error = [[self class] errorWithCode:status]; + } + return (status == errSecSuccess);} + + +- (BOOL)deleteItem:(NSError *__autoreleasing *)error { + OSStatus status = SAMKeychainErrorBadArguments; + if (!self.service || !self.account) { + if (error) { + *error = [[self class] errorWithCode:status]; + } + return NO; + } + + NSMutableDictionary *query = [self query]; +#if TARGET_OS_IPHONE + status = SecItemDelete((__bridge CFDictionaryRef)query); +#else + // On Mac OS, SecItemDelete will not delete a key created in a different + // app, nor in a different version of the same app. + // + // To replicate the issue, save a password, change to the code and + // rebuild the app, and then attempt to delete that password. + // + // This was true in OS X 10.6 and probably later versions as well. + // + // Work around it by using SecItemCopyMatching and SecKeychainItemDelete. + CFTypeRef result = NULL; + [query setObject:@YES forKey:(__bridge id)kSecReturnRef]; + status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + if (status == errSecSuccess) { + status = SecKeychainItemDelete((SecKeychainItemRef)result); + CFRelease(result); + } +#endif + + if (status != errSecSuccess && error != NULL) { + *error = [[self class] errorWithCode:status]; + } + + return (status == errSecSuccess); +} + + +- (NSArray *)fetchAll:(NSError *__autoreleasing *)error { + NSMutableDictionary *query = [self query]; + [query setObject:@YES forKey:(__bridge id)kSecReturnAttributes]; + [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; +#if __IPHONE_4_0 && TARGET_OS_IPHONE + CFTypeRef accessibilityType = [SAMKeychain accessibilityType]; + if (accessibilityType) { + [query setObject:(__bridge id)accessibilityType forKey:(__bridge id)kSecAttrAccessible]; + } +#endif + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + if (status != errSecSuccess && error != NULL) { + *error = [[self class] errorWithCode:status]; + return nil; + } + + return (__bridge_transfer NSArray *)result; +} + + +- (BOOL)fetch:(NSError *__autoreleasing *)error { + OSStatus status = SAMKeychainErrorBadArguments; + if (!self.service || !self.account) { + if (error) { + *error = [[self class] errorWithCode:status]; + } + return NO; + } + + CFTypeRef result = NULL; + NSMutableDictionary *query = [self query]; + [query setObject:@YES forKey:(__bridge id)kSecReturnData]; + [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; + status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if (status != errSecSuccess) { + if (error) { + *error = [[self class] errorWithCode:status]; + } + return NO; + } + + self.passwordData = (__bridge_transfer NSData *)result; + return YES; +} + + +#pragma mark - Accessors + +- (void)setPasswordObject:(id)object { + self.passwordData = [NSKeyedArchiver archivedDataWithRootObject:object]; +} + + +- (id)passwordObject { + if ([self.passwordData length]) { + return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData]; + } + return nil; +} + + +- (void)setPassword:(NSString *)password { + self.passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; +} + + +- (NSString *)password { + if ([self.passwordData length]) { + return [[NSString alloc] initWithData:self.passwordData encoding:NSUTF8StringEncoding]; + } + return nil; +} + + +#pragma mark - Synchronization Status + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE ++ (BOOL)isSynchronizationAvailable { +#if TARGET_OS_IPHONE + // Apple suggested way to check for 7.0 at runtime + // https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/SupportingEarlieriOS.html + return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1; +#else + return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4; +#endif +} +#endif + + +#pragma mark - Private + +- (NSMutableDictionary *)query { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; + [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; + + if (self.service) { + [dictionary setObject:self.service forKey:(__bridge id)kSecAttrService]; + } + + if (self.account) { + [dictionary setObject:self.account forKey:(__bridge id)kSecAttrAccount]; + } + +#ifdef SAMKEYCHAIN_ACCESS_GROUP_AVAILABLE +#if !TARGET_IPHONE_SIMULATOR + if (self.accessGroup) { + [dictionary setObject:self.accessGroup forKey:(__bridge id)kSecAttrAccessGroup]; + } +#endif +#endif + +#ifdef SAMKEYCHAIN_SYNCHRONIZATION_AVAILABLE + if ([[self class] isSynchronizationAvailable]) { + id value; + + switch (self.synchronizationMode) { + case SAMKeychainQuerySynchronizationModeNo: { + value = @NO; + break; + } + case SAMKeychainQuerySynchronizationModeYes: { + value = @YES; + break; + } + case SAMKeychainQuerySynchronizationModeAny: { + value = (__bridge id)(kSecAttrSynchronizableAny); + break; + } + } + + [dictionary setObject:value forKey:(__bridge id)(kSecAttrSynchronizable)]; + } +#endif + + return dictionary; +} + + ++ (NSError *)errorWithCode:(OSStatus) code { + static dispatch_once_t onceToken; + static NSBundle *resourcesBundle = nil; + dispatch_once(&onceToken, ^{ + NSURL *url = [[NSBundle bundleForClass:[SAMKeychainQuery class]] URLForResource:@"SAMKeychain" withExtension:@"bundle"]; + resourcesBundle = [NSBundle bundleWithURL:url]; + }); + + NSString *message = nil; + switch (code) { + case errSecSuccess: return nil; + case SAMKeychainErrorBadArguments: message = NSLocalizedStringFromTableInBundle(@"SAMKeychainErrorBadArguments", @"SAMKeychain", resourcesBundle, nil); break; + +#if TARGET_OS_IPHONE + case errSecUnimplemented: { + message = NSLocalizedStringFromTableInBundle(@"errSecUnimplemented", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecParam: { + message = NSLocalizedStringFromTableInBundle(@"errSecParam", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecAllocate: { + message = NSLocalizedStringFromTableInBundle(@"errSecAllocate", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecNotAvailable: { + message = NSLocalizedStringFromTableInBundle(@"errSecNotAvailable", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecDuplicateItem: { + message = NSLocalizedStringFromTableInBundle(@"errSecDuplicateItem", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecItemNotFound: { + message = NSLocalizedStringFromTableInBundle(@"errSecItemNotFound", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecInteractionNotAllowed: { + message = NSLocalizedStringFromTableInBundle(@"errSecInteractionNotAllowed", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecDecode: { + message = NSLocalizedStringFromTableInBundle(@"errSecDecode", @"SAMKeychain", resourcesBundle, nil); + break; + } + case errSecAuthFailed: { + message = NSLocalizedStringFromTableInBundle(@"errSecAuthFailed", @"SAMKeychain", resourcesBundle, nil); + break; + } + default: { + message = NSLocalizedStringFromTableInBundle(@"errSecDefault", @"SAMKeychain", resourcesBundle, nil); + } +#else + default: + message = (__bridge_transfer NSString *)SecCopyErrorMessageString(code, NULL); +#endif + } + + NSDictionary *userInfo = nil; + if (message) { + userInfo = @{ NSLocalizedDescriptionKey : message }; + } + return [NSError errorWithDomain:kSAMKeychainErrorDomain code:code userInfo:userInfo]; +} + +@end diff --git a/evernote-sdk-ios/3rdParty/SSKeychain/SSKeychain.h b/evernote-sdk-ios/3rdParty/SSKeychain/SSKeychain.h deleted file mode 100644 index 0d27bd0..0000000 --- a/evernote-sdk-ios/3rdParty/SSKeychain/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/evernote-sdk-ios/3rdParty/SSKeychain/SSKeychain.m b/evernote-sdk-ios/3rdParty/SSKeychain/SSKeychain.m deleted file mode 100644 index b3a4712..0000000 --- a/evernote-sdk-ios/3rdParty/SSKeychain/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/evernote-sdk-ios/internal/ENCredentials.m b/evernote-sdk-ios/internal/ENCredentials.m index 268a857..8216974 100755 --- a/evernote-sdk-ios/internal/ENCredentials.m +++ b/evernote-sdk-ios/internal/ENCredentials.m @@ -28,7 +28,7 @@ */ #import "ENCredentials.h" -#import "SSKeychain.h" +#import "SAMKeychain.h" @interface ENCredentials() @@ -63,7 +63,7 @@ - (BOOL)saveToKeychain { // auth token gets saved to the keychain NSError *error; - BOOL success = [SSKeychain setPassword:_authenticationToken + BOOL success = [SAMKeychain setPassword:_authenticationToken forService:self.host account:self.edamUserId error:&error]; @@ -76,13 +76,13 @@ - (BOOL)saveToKeychain - (void)deleteFromKeychain { - [SSKeychain deletePasswordForService:self.host account:self.edamUserId]; + [SAMKeychain deletePasswordForService:self.host account:self.edamUserId]; } - (NSString *)authenticationToken { NSError *error; - NSString *token = [SSKeychain passwordForService:self.host account:self.edamUserId error:&error]; + NSString *token = [SAMKeychain passwordForService:self.host account:self.edamUserId error:&error]; if (!token) { NSLog(@"Error getting password from keychain: %@", error); }