Enumerate all Keychain items in my iOS application
SecItemCopyMatching
is the right call for that. First we build our query dictionary so that the items' attributes are returned in dictionaries, and that all items are returned:
NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
(__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
nil];
As SecItemCopyMatching
requires at least the class of the returned SecItem
s, we create an array with all the classes…
NSArray *secItemClasses = [NSArray arrayWithObjects:
(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
(__bridge id)kSecClassCertificate,
(__bridge id)kSecClassKey,
(__bridge id)kSecClassIdentity,
nil];
...and for each class, set the class in our query, call SecItemCopyMatching
, and log the result.
for (id secItemClass in secItemClasses) {
[query setObject:secItemClass forKey:(__bridge id)kSecClass];
CFTypeRef result = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
NSLog(@"%@", (__bridge id)result);
if (result != NULL) CFRelease(result);
}
In production code, you should check that the OSStatus
returned by SecItemCopyMatching
is either errSecItemNotFound
(no items found) or errSecSuccess
(at least one item was found).
How can I enumerate all Keychain items in my OS X application?
You're providing an empty dictionary and not a valid query.
If you take the code from the answer you were looking at and drop it into your project:
NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
(__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
nil];
NSArray *secItemClasses = [NSArray arrayWithObjects:
(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
(__bridge id)kSecClassCertificate,
(__bridge id)kSecClassKey,
(__bridge id)kSecClassIdentity,
nil];
for (id secItemClass in secItemClasses) {
[query setObject:secItemClass forKey:(__bridge id)kSecClass];
CFTypeRef result = NULL;
SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
NSLog(@"%@", (__bridge id)result);
if (result != NULL) CFRelease(result);
}
You'll have a happier result.
EDITED to add the CoreFoundation equivalent
There's no reason why you can't include the Cocoa framework in your MacOS command line tool (which is what I'm assuming you are writing). What a command line tool can't easily include is the AppKit UI framework.
Anyways, here is the CoreFoundation equivalent:
CFMutableDictionaryRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
CFTypeRef types[5];
types[0] = kSecClassGenericPassword;
types[1] = kSecClassInternetPassword;
types[2] = kSecClassCertificate;
types[3] = kSecClassKey;
types[4] = kSecClassIdentity;
CFArrayRef secItemClasses = CFArrayCreate(NULL, (void *)types, 5, &kCFTypeArrayCallBacks);
CFIndex i, c = CFArrayGetCount(secItemClasses);
for(i = 0; i{
CFTypeRef secItemClass = CFArrayGetValueAtIndex(secItemClasses,i);
CFDictionarySetValue(query, kSecClass, secItemClass);
CFTypeRef result = NULL;
SecItemCopyMatching(query, &result);
NSLog(@"%@", (__bridge id)result);
if (result != NULL) CFRelease(result);
}
CFRelease(secItemClasses);
CFRelease(query);
When I put this into my own test app, I'm seeing quite a large dump of various keychain items and certificates.
How to delete all keychain items accessible to an app?
Do it for all classes
Objective-C:
NSArray *secItemClasses = @[(__bridge id)kSecClassGenericPassword,
(__bridge id)kSecClassInternetPassword,
(__bridge id)kSecClassCertificate,
(__bridge id)kSecClassKey,
(__bridge id)kSecClassIdentity];
for (id secItemClass in secItemClasses) {
NSDictionary *spec = @{(__bridge id)kSecClass: secItemClass};
SecItemDelete((__bridge CFDictionaryRef)spec);
}
Swift:
let secItemClasses = [kSecClassGenericPassword, kSecClassInternetPassword, kSecClassCertificate, kSecClassKey, kSecClassIdentity]
for itemClass in secItemClasses {
let spec: NSDictionary = [kSecClass: itemClass]
SecItemDelete(spec)
}
Swift 4 Get Keychain Data from Another Project
Not at this point.
You are able to add multiple applications to a Keychain Access Group within an app, but you would have had to do that within the original app you no longer have access to.
More information on Keychain Access Groups.
It would be a big security concern if anyone could access anything within keychain without explicit permission.
Sharing Keychain Items in iOS
You can refer to the Apple documentation here: https://developer.apple.com/library/ios/documentation/security/Reference/keychainservices/Reference/reference.html
It details how to share items across two or more apps using a keychain-access-groups entitlement
Private Keychain store
You can't.
The security boundary for the KeyChain is the app (Or the KeyChain identifier across multiple apps from the same developer if you enable KeyChain sharing).
Once your framework is embedded in the client app, it is part of the client app. It doesn't have its own context or process space or anything to distinguish its code from the client code.
If code in your framework puts something in the KeyChain then, to iOS, it is the client app that has put something in the KeyChain, and there is no reason to keep a secret from itself.
Even if you could create a KeyChain just for your framework, presumably the code that puts the information in the KeyChain is in your framework, so an attacker could just decompile your framework to obtain the information.
Can we access keychain items that are saved before enabling keychain sharing from app sharing same app group?
Before enabling keychain sharing all keychain items "accessGroup" is (AppIdentifierPrefix).bundleIdentifier, which is changed to (AppIdentifierPrefix).keyChainGroupName after turning it on.
Workaround is to remove all keychain items by accessing those through keychains.
AWSUICKeyChainStore *keychain = [AWSUICKeyChainStore keyChainStoreWithService:@"ServiceName"];
for (NSDictionary *dictionary in keychain.allItems)
if ([dictionary[@"accessGroup"] isEqualToString:"(AppIdentifierPrefix).bundleIdentifier"])
[keychain removeItemForKey:dictionary[@"key"]];
How to detect if iOS Keychain items not available yet? (before first unlock)
As far as I know "Error Code -25308 (errSecInteractionNotAllowed)" is returned, but I haven't been able to verify yet.
Source: https://developer.apple.com/documentation/security/1542001-security_framework_result_codes/errsecinteractionnotallowed?language=objc
How to list certificates from the iPhone keychain inside my app?
The Junos Pulse app is apparently getting its access via a VPN plugin which is a private API supplied by Apple on an invitation-only basis. That API is giving the app access to those certificates otherwise accessible only to built-in iOS apps like Safari.
Review the following which were very helpful when I was researching the topic:
iOS get Configuration Profiles that are installed
(Apple Development post linked in one of the answers)
https://devforums.apple.com/message/660579#660579
Related Topics
Getting All Cookies from Wkwebview
Xcode 9 Error: "Iphone Has Denied the Launch Request"
How to Change Multiplier Property For Nslayoutconstraint
Add Image to Uialertaction in Uialertcontroller
How to Debug iOS 8 Extensions With Nslog
How to Handle Background Audio Playing While iOS Device Is Locked or on Another Application
Add "...Read More" to the End of Uilabel
Get Indexpath of Uitableviewcell on Click of Button from Cell
Swrevealviewcontroller Without Using Navigationcontroller
How to Perform Wireless Debugging in Xcode 9 With iOS 11, Apple Tv 4K, etc
Cordova App Not Displaying Correctly on Iphone X (Simulator)
How to Segue Programmatically in iOS Using Swift
How to Detect Orientation Change
How to Write Text on Image in Objective-C (Ios)
When to Use Dequeuereusablecellwithidentifier VS Dequeuereusablecellwithidentifier: Forindexpath
Programmatically Align a Toolbar on Top of the Iphone Keyboard