KeyChain access on iOS 11 simulator requires

Hello,

I've been doing some maintenance on an old iOS app and been getting errors adding items to the keychain on the iOS Simulator (I haven't tried deploying the app to a real phone just yet).

I'd like to confirm what I think is the case:

  • The iOS simulator requires the keychain-access-groups entitlement to access the KeyChain.
  • That implies you need to provision the simulator with approprate certificates, et al.

The symptoms I'm seeing is that any call to SecKeyChain.Add() returns SecStatusCode.Parm. See below for an example.
I've tried setting pretty much every combination of property on SecRecord.
And have confirmed the Xamarin KeyChain sample app does not work on the simulator.

public static void SaveTicket(string ticket)
{
    var record = new SecRecord(SecKind.GenericPassword);
    record.Account = "ticket";
    record.ValueData = ticket;
    SecStatusCode sRes = SecKeyChain.Add(record);
    // sRes is always Parm
}

Murray

Answers

  • kharpsterkharpster Member ✭✭
    edited May 2018
    I am having the same issue in VS 2017 (latest build) running on my PC, running the code using an iOS simulator (11.3), using Xcode 9.3 on my Mac. The query functionality seems to work as it returns "SecStatusCode.ItemNotFound".

    Has anyone found a solution or am I just missing something?

    Also, the Xamarin Keychain sample (developer.xamarin.com/samples/monotouch/Keychain/) produces the same result.
  • MrDaneeyulMrDaneeyul Member ✭✭

    I had the same issue and I believe I've resolved it. Visual Studio 2017 15.6.6 on Windows, iOS simulator 11.3, Xcode 9.3 on the Mac. It kept returning SecStatusCode.Param:

    var statusCode = SecKeyChain.Add(new SecRecord(SecKind.GenericPassword)
    {
            Service = SERVICE_ID,
            Label = SERVICE_ID,
            Account = userID,
            ValueData = NSData.FromString(password, NSStringEncoding.UTF8),
            Generic = NSData.FromString(string.Empty),
            Accessible = secAccessible,
            Synchronizable = isSynchronizable
    });
    

    Given that SecStatusCode.Param means some of the parameters are wrong, I tried a large variety of different properties--removing some, adding some, etc., and it made no difference. So I added keychain-access-groups to Entitlements.plist to check if it would work, and I got the following build error in Visual Studio:

    Could not find any available provisioning profiles for iOS

    This is probably because the specific Mac I was using the simulator on doesn't have provisioning profiles, etc., installed, but everywhere I've looked states that the simulator doesn't need these. However, when I tested it on our other Mac with our provisioning profiles, it seems to have worked. ¯\_(ツ)_/¯

    So anyway, yes, the answer is to head into Entitlements.plist in the iOS project -> Keychain -> Check "Enable Keychain". If Entitlements.plist doesn't exist for you, create a new file in your iOS project, paste this in (with your bundle id and the apple url without spaces--I can't post urls yet :smile:), then name it "Entitlements.plist":

    <?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>keychain-access-groups</key>
        <array>
            <string>com.yourcompany.yourappnamehere</string>
        </array>
    </dict>
    </plist>
    

    After that, you'll need to right click your iOS project in Visual Studio -> Properties -> iOS Bundle Signing. Make sure Configuration at the top is "Debug" and Platform is "iPhoneSimulator". Under "Custom Entitlements" enter "Entitlements.plist" (or find it with the open button to the right of the field).

    I haven't confirmed whether the other build configurations will need this same setting, but I'm about 90% sure they will.

    Hope this helps. :)

  • kharpsterkharpster Member ✭✭
    edited May 2018

    MrDaneeyul,

    I had already tried adding the keychain-access-groups and entitlement.plist and was getting the same thing as you, Could not find any available provisioning profiles for iOS. And like yourself, the Mac I was using the simulator on did not have any provisioning profiles. This seems to be an issue at the moment as after I added a provisioning profile to my Mac, the application ran without any problem.

    So it seems that for the moment, contrary to what the documentation says, in addition to the keychain-access-groups and entitlement.plist requirements, you also have to have at least one provisioning profile for a device setup on the Mac for the SecKeyChain.Add(record) method to work properly.

    Thank you for your response, it allowed me to identify the culprit!

  • MrDaneeyulMrDaneeyul Member ✭✭
    edited May 2018

    No problem!

    I've done some more research into this and came to the same conclusion you did independently. Looks like keychain-access-groups is intended to be for sharing the keychain, which didn't really sound like what I wanted... I was mystified that it worked but marked it down just as another bizarre Apple thing.

    Looks like Entitlements.plist actually breaks our build if it's kept in the AppStore/TestFlight build configurations, so I'm going to only keep it in the Debug configuration. We've confirmed at least that saving to the keychain works without Entitlements.plist in our TestFlight build.

    Seems likely that this is some kind of bug.

  • kharpsterkharpster Member ✭✭
    edited May 2018

    Just out of curiosity based on your last response, I removed the keychain-access-groups and the entitlement.plist from my project and tried to launch my app in the simulator (with a provisioning profile). Oddly enough, it works just fine. The only thing prior to this thread I could find was an issue with the iPhone 10 simulator which threw an error ("Could not save account to KeyChain: -34018") if the keychain-access-groups was not included in the build (I tested it and I do not get the error). It is starting to look more and more like a undocumented feature (bug) that requires a provisioning profile exist on your Mac for theSecKeyChain.Add(record) to work on a simulator build (at least with iOS 11.x). I venture to guess you could do the same as I did in your simulator build and it would still run.

  • MrDaneeyulMrDaneeyul Member ✭✭

    I did attempt it after removing keychain-access-groups entirely, and still got the good ol' SecStatusCode.Param response. While writing my previous comment, I believe I did actually have it working, but... temporarily. So I had to backtrack. More than anything, that inconsistency screams "bug!" to me.

    I don't mind having it in the debug build anyway. It might be a problem if we needed other options, but I suppose in that case I could use different .plist files for custom entitlements in the other build configurations.

  • SteveShaw.5557SteveShaw.5557 USMember ✭✭✭
    edited August 2018

    For me, it was necessary to add (and refer to) Entitlements.plist in my Debug + iPhoneSimulator config, as described by @MrDaneeyul

    I first tried to download and install a provisioning profile on my mac from Apple dev center, but that had no effect (or maybe I didn't do it right.) Then I realized that only my Release configs referred to Entitlements.plist, so I needed to add that to Debug configs also.

  • techatetechate Member ✭✭

    This is a useful post on an old iOS app. These apps have many issues making or working on the new a project. I have found icloud customer service it very useful for these type of apps

Sign In or Register to comment.