Jak Hammond
Jak Hammond

Reputation: 1500

Xamarin.iOS KeyChain Identity not persisting

I have created a self-signed .pfx file that when I drag onto the emulator, the import screen appears, I can click through and then using select * from cert; on the emulators Keychain, I can see the imported certificate.

When I load this certificate in code and attempt to add it, I am getting a Success back from the save operation but on subsequent attempts to access the identity, it is returning ItemNotFound, further to that, when I inspect the KeyChain after the import there is no cert in the table either.

await certStream.CopyToAsync(ms);

var options = NSDictionary.FromObjectsAndKeys(new[]
{
   NSObject.FromObject("CertPassword")
}, new[] 
{
    SecImportExport.Passphrase
});

var result = SecImportExport.ImportPkcs12(ms.ToArray(), options, out 
    NSDictionary[] imports);
if (result != SecStatusCode.Success)
    throw new Exception("Failed importing certificate identity");

var identity = imports[0][SecImportExport.Identity];
certRecord.SetValueRef(new SecIdentity(identity.Handle));
var identityImportResult = SecKeyChain.Add(certRecord);

var savedIdentity = SecKeyChain.QueryAsRecord(new 
    SecRecord(SecKind.Identity)
{
    Label = "ApplicationIdentityCertificate"
}, out SecStatusCode savedResult);

Reading round, I have ensured that there is a Entitlements associated with the emulator and that also, it has the keychain sharing entitlement as there appears to be anecdotal evidence that this can sometimes also impact the ability to save to the Keychain.

Upvotes: 0

Views: 140

Answers (1)

Jak Hammond
Jak Hammond

Reputation: 1500

So I finally managed to get this working. It turns out I was missing a pretty simple method that is available on the SecKeyChain class.

var identity = imports[0][SecImportExport.Identity];
SecKeyChain.AddIdentity(new SecIdentity(identity.Handle));

The above snippet is the change I needed to make and now the identity is being stored in the Keychain with the correct bundle ID and our application can load the certificate and the private key, for whatever reason, adding it via the SecKeyChain.Add() method was not working for identities.

Upvotes: 1

Related Questions