2010-05-05 22 views
6

Cómo agregar identidad de seguridad (certificado + clave privada) al llavero iPhone? Tengo el archivo .p12 en la aplicación. Puedo conseguir la identidad de ella usando SecPKCS12Import() pero cuando trato de hacer lo siguiente:Cómo agregar identidad de seguridad (certificado + clave privada) al llavero iPhone?

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); 

estoy consiguiendo error = -25 291 -> No hay resultados de confianza están disponibles. ¿Qué estoy haciendo mal?

Respuesta

4

sólo tiene que utilizar 1 parámetro en el diccionario de atributos para agregar a la identidad Llavero:

NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];  
[secIdentityParams setObject:(id)myIdentity forKey:(id)kSecValueRef]; 
OSStatus status = SecItemAdd((CFDictionaryRef) secIdentityParams, NULL); 
+0

OMG, eso fue todo, no poner el atributo de clase hecho que funcione. ¿Por qué O por qué el marco de seguridad es tan miserablemente complicado, mal documentado y meticuloso? Tanto tiempo perdido. –

2

Usando kSecValueRef como único parámetro funciona perfectamente. ¿Sabes por qué la función falla cuando otros parámetros, como p. kSecClass, se proporcionan? El Servicios Llavero de referencia documenta el primer parámetro de SecItemAdd() de la siguiente manera:

un diccionario que contiene una clase de artículos par clave-valor [...] y opcional atribuir pares de valores clave [...] especificando los atributos del artículo valores.

I supone que kSecClass es un parámetro obligatorio que debe estar siempre presente, ya sea utilizando las SecItemAdd() oder SecItemCopyMatching(). Certificate, Key, and Trust Services Tasks on iOS explica el proceso de añadir un SecIdentityRef al llavero de la siguiente manera (Listado 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; 
} 

¿Es este ejemplo simplemente se equivocan?

1

Logré obtener servicios de llavero para devolver una referencia de llavero persistente al agregar un nuevo SecIdentityRef a través de SecItemAdd(). Aquí está el código de trabajo:

- (NSData *)persistentKeychainReferenceForIdentity:(SecIdentityRef)identity 
{ 
    NSData *persistentRef = nil; 
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: 
           (id)identity, kSecValueRef, 
           (id)kCFBooleanTrue, kSecReturnPersistentRef, 
           nil]; 
    OSStatus itemAddStatus = SecItemAdd((CFDictionaryRef)attributes, 
             (CFTypeRef *)&persistentRef); 
    if (itemAddStatus != errSecSuccess) 
    { 
     return nil; 
    }  

    return persistentRef; 
} 

Espero que esto ayude a los demás también.

+0

¿Qué haces con esa ref persistente? ¿Almacenarlo en las preferencias del usuario para acceder a él más tarde y luego buscar en el llavero desde allí? – lostintranslation

Cuestiones relacionadas