Comment puis-je importer par programme un certificat dans le trousseau de mon application iOS et transmettre l'identité à un serveur si nécessaire?

Je suis en train de travailler sur un iOS5 application qui va faciliter les paiements mobiles entre deux utilisateurs. Dans le cadre du processus de paiement, l'expéditeur et le destinataire ont besoin de communiquer avec un serveur. Le serveur exige que les deux parties présentent leurs identités lorsqu'une authentification défi est lancé au moment de la connexion.

Actuellement, j'ai codé en dur le processus de certificat en utilisant les deux méthodes suivantes dans mon code:

NSURLConnection Délégué didReceiveAuthenticationChallenge

(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:    (NSURLAuthenticationChallenge *)challenge
{
NSLog(@"Authentication challenge");

//Load Certificate
NSString *path = [[NSBundle mainBundle] pathForResource:@"PKCS12" ofType:@"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;

SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);

SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);

NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];

[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}

C Méthode extractIdentityAndTrust

OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;

CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };

CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);

if (securityError == 0) {
    CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
    const void *tempIdentity = NULL;
    tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
    *identity = (SecIdentityRef)tempIdentity;
    const void *tempTrust = NULL;
    tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
    *trust = (SecTrustRef)tempTrust;
}

if (options) {
    CFRelease(options);
}

return securityError;
}

J'ai testé ce code à de nombreuses reprises et ont été couronnés de succès. Maintenant, je suis en train d'avancer et de permettre à la appropriée de l'identité pour être stockés et récupérés à partir de l'application trousseau d'accès. Mon objectif est de permettre aux utilisateurs d'importer leurs P12 fichiers via iTunes Partage de Fichiers ou Dropbox, et de les enregistrer sur le trousseau de clés.

J'ai regardé la documentation d'Apple pour L'obtention et l'Utilisation Persistante de Keychain de Références et ont été incapables de trouver comment importer de l'identité. Leur code est un peu confus pour moi, car ils utilisent les variables non déclarées/références (en particulier le

&persistent_ref

variable). Si quelqu'un pouvait aider à le déchiffrer, ce serait grandement apprécié.

TL;DR: Comment faire pour enregistrer le contenu d'un fichier P12 dans mon iOS5 application trousseau et le récupérer plus tard à s'en remettre à un NSURLConnection didReceiveAuthenticationChallenge méthode?

source d'informationauteur derekmckinnon