Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add security identity (certificate + private key) to iPhone keychain?

How to add security identity (certificate + private key) to iPhone keychain? I have .p12 file in application. I can get identity from it using SecPKCS12Import() but when i try to do the following:

NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];    
[secIdentityParams setObject:(id)kSecClassIdentity forKey:(id)kSecClass];
[secIdentityParams setObject:label forKey:(id)kSecAttrLabel];
[secIdentityParams setObject:(id)myIdentity forKey:(id)kSecValueRef];

status = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);

I am getting error = -25291 -> No trust results are available. What am I doing wrong?

like image 783
Dmitry Likhachev Avatar asked May 05 '10 12:05

Dmitry Likhachev


2 Answers

Just use 1 parameter in attributes dictionary to add identity to keychain:

NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];    
[secIdentityParams setObject:(id)myIdentity forKey:(id)kSecValueRef];
OSStatus status = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL);
like image 173
Dmitry Likhachev Avatar answered Sep 19 '22 10:09

Dmitry Likhachev


Using kSecValueRef as the only parameter works perfectly. Do you know why the function fails when other parameters, like e.g. kSecClass, are provided? The Keychain Services Reference documents the first parameter of SecItemAdd() as follows:

A dictionary containing an item class key-value pair [...] and optional attribute key-value pairs [...] specifying the item's attribute values.

I assumed that kSecClass is a mandatory parameter that must always be present, either when using SecItemAdd() oder SecItemCopyMatching(). Certificate, Key, and Trust Services Tasks on iOS explains the process of adding a SecIdentityRef to the Keychain as follows (Listing 2-3):

CFDataRef persistentRefForIdentity(SecIdentityRef identity)
{
    OSStatus status;

    CFTypeRef  identity_handle = NULL;
    const void *keys[] =   { kSecReturnPersistentRef, kSecValueRef };
    const void *values[] = { kCFBooleanTrue,          identity };
    CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values,
                                              2, NULL, NULL);
    status = SecItemAdd(dict, &persistent_ref);

    if (dict)
        CFRelease(dict);

    return (CFDataRef)persistent_ref;
}

Is this example just wrong?

like image 35
Manuel Binna Avatar answered Sep 22 '22 10:09

Manuel Binna