2010-05-05 6 views
6

Comment ajouter une identité de sécurité (certificat + clé privée) au trousseau iPhone? J'ai le fichier .p12 dans l'application. Je peux obtenir l'identité de l'aide SecPKCS12Import() mais lorsque je tente de faire ce qui suit:Comment ajouter une identité de sécurité (certificat + clé privée) au trousseau 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); 

J'obtiens l'erreur = -25291 -> Aucun résultat de confiance sont disponibles. Qu'est-ce que je fais de mal?

Répondre

4

Il suffit d'utiliser 1 paramètre dans les attributs de dictionnaire pour ajouter l'identité au trousseau:

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

OMG, c'était ça, ne mettant pas l'attribut de la classe a fait fonctionner. Pourquoi O pourquoi le cadre de sécurité est-il si compliqué, si mal documenté et si compliqué? Tellement de temps perdu. –

2

En utilisant kSecValueRef comme le seul paramètre fonctionne parfaitement. Savez-vous pourquoi la fonction échoue lorsque d'autres paramètres, par ex. kSecClass, sont fournis? Le porte-clés des services de référence documente le premier paramètre de SecItemAdd() comme suit:

Un dictionnaire contenant une classe d'élément paire clé-valeur [...] et en option attribut paires clé-valeur [...] spécifiant les valeurs de l'élément.

Je suppose que kSecClass est un paramètre obligatoire qui doit toujours être présent, que ce soit lors de l'utilisation SecItemAdd() oder SecItemCopyMatching(). Certificate, Key, and Trust Services Tasks on iOS explique le processus d'ajout d'un SecIdentityRef au trousseau comme suit (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; 
} 

Cet exemple est tout simplement faux?

1

J'ai réussi à obtenir des services de trousseau pour renvoyer une référence de trousseau persistant lors de l'ajout d'un nouveau SecIdentityRef via SecItemAdd(). Voici le code de travail:

- (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; 
} 

J'espère que cela aide les autres aussi.

+0

Que faites-vous avec cette ref persistante? Stockez-le dans les préférences de l'utilisateur pour y accéder plus tard, puis chercher dans le trousseau à partir de là? – lostintranslation

Questions connexes