Keychain Services API fails with errSecNotAvailable in iphonesimulator 6.0

谁说胖子不能爱 提交于 2019-12-21 17:26:51

问题


Calls to the the Keychain Services fail with errSecNotAvailable when executing a target using the command line tools and the iphone simulator is set to Hardware version 6.0 (10A403). If I change the simulator version to other previous version (4.3, 5.0, 5.1) and re-execute using the same command line script the calls succeed.

I'm running latest XCode 4.5 and the command line tools were downloaded from within XCode.

To reproduce this error just do the following:

  1. Setup an ios library project with a OCUnit target
  2. Set Base SDK to 6.0
  3. Set iOS Deployment Target to 4.3
  4. Copy and paste the code st the end of the post into the test project (it will only try to store a password and retrieve it)
  5. Add the Security.framework to the OCUnit target

Execute the OCUnit target in XCode and see the test pass with whatever Hardware Version is set in the iphone simulator (just change it between executions).

Execute the OCUnit target from the command line using:

xcodebuild -target TARGET_NAME_HERE -sdk iphonesimulator -configuration Release TEST_AFTER_BUILD=YES

with iphone simulator set to Hardware Version 6.0 and the test will fail. If you change the iphone simulator Hardware Version to 4.3, 5.0 or 5.1 and execute the command line script again the test will succeed.

Is this a command line tool problem? an iphone simulator problem? an OCUnit target running from the command line problem?

Who likes having unit tests that only pass when comets are aligned??

Any ideas?

Here is the code:

#define KEYCHAIN_ITEM_ATTRIBUTES (id)kSecClassGenericPassword, kSecClass, @"MyService", kSecAttrService, @"MyPassword", kSecAttrAccount

const NSString* MyPassword = @"blabla";

- (void)testExample
{
    // remove previous keychain item
    OSStatus status = SecItemDelete((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES, nil]);
    NSLog(@"SecItemDelete status:%ld",status);
    NSParameterAssert(status == errSecSuccess || status == errSecItemNotFound);

    // add keychain item with new value
    NSData *data = [MyPassword dataUsingEncoding:NSUTF8StringEncoding];
    status = SecItemAdd((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES, data, kSecValueData, nil], NULL);
    NSLog(@"SecItemAdd status:%ld",status);
    NSParameterAssert(status == errSecSuccess);

    // get password
    status = SecItemCopyMatching((CFTypeRef)[NSDictionary dictionaryWithObjectsAndKeys:KEYCHAIN_ITEM_ATTRIBUTES,
                                             kSecMatchLimitOne, kSecMatchLimit, kCFBooleanTrue, kSecReturnData, nil], (CFTypeRef *)&data);
    NSLog(@"SecItemCopyMatching status:%ld",status);
    NSParameterAssert(status == errSecSuccess);

    if (status == errSecItemNotFound)
        NSLog(@"SecItemCopyMatching status:%ld", status);
    else
        NSLog(@"SecItemCopyMatching result:%@",[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
}

Regarding securityd daemon not being launched, I can check it IS being launched, using

launchctl list | grep securityd

after the simulator starts, and getting

-   0   com.apple.iPhoneSimulator:com.apple.securityd

I also tried stopping this securityd daemon and launch another manually... I looked at GTM's RunIPhoneUnitTest.sh script for a simple line I could use, but when I try this

launchctl submit -l ios6securityd -- /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk/usr/libexec/securityd

gives me a -5 status code on that daemon.


回答1:


I came across this because I was having trouble getting keychain access when trying to run my unit tests from the Xcode 4.5.1 UI. Luckily, the breakage is something I'm familiar with from CI builds with most previous Xcode versions as well, which is that the simulator's securityd isn't properly launched.

Try launching securityd first, and see if that helps:

#!/bin/bash

simulator_root=`xcodebuild -version -sdk iphonesimulator Path`
"${simulator_root}/usr/libexec/securityd"

That worked for me.



来源:https://stackoverflow.com/questions/13087175/keychain-services-api-fails-with-errsecnotavailable-in-iphonesimulator-6-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!