2009-09-22 10 views
20

Je me bats avec une authentification de certificat client. Lorsqu'un serveur a besoin d'un diplôme (un certificat dans ce cas), cette méthode est appelée à partir NSURLConnection délégué:iPhone: authentification par certificat client HTTPS

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

Je veux charger un certificat à partir d'un fichier, remplir un titre et exécuter cette méthode:

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

Mais je ne sais pas comment initialiser (ou remplir) un paramètre SecIdentityRef . Voici mon code qui crée les informations d'identification:

NSString *certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"]; 
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath]; 

SecIdentityRef myIdentity; // ??? 

SecCertificateRef myCert = SecCertificateCreateWithData(NULL, (CFDataRef)certData); 
[certData release]; 
SecCertificateRef certArray[1] = { myCert }; 
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL); 
CFRelease(myCert); 
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity 
            certificates:(NSArray *)myCerts 
            persistence:NSURLCredentialPersistencePermanent]; 
CFRelease(myCerts); 

Quelqu'un sait-il comment le résoudre? Merci.


J'ai enfin trouvé la solution, mais un nouveau problème est ici:

mon client ne transmet pas le certificat au serveur. Une fois le serveur demande le certificat, l'application exécute cette méthode:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

et je remplis les informations d'identification (comme je l'ai mentionné ci-dessus), mais la fin de la connexion avec une erreur: NSURLErrorDomain -1206. Selon les journaux du serveur, le certificat client n'est pas envoyé par l'application.

Quelqu'un a-t-il déjà eu ce comportement? Ai-je besoin de vérifier le certificat dans l'application? Ou autre chose pour le faire fonctionner? Je peux fournir mon code actuel si cela peut vous aider. Merci pour toutes les idées ...

Répondre

0

Bien sûr, le problème était avec le simulateur d'iPhone dans Xcode :) Après la mise à jour à la version 3.1, il a commencé à travailler ...

+3

Juste un petit conseil pour rendre vos questions plus lisibles: les questions post nouvelles réponses que Do not. Cela tend à rendre les fils plus difficiles à lire. Rappelez-vous que votre question sera probablement utile à quelqu'un d'autre et qu'il est important pour eux de voir votre processus et la réponse finale. Merci! – mtmurdock

4

J'utilise ces étapes:

  1. SecIdentityRef extrait du fichier de certificat pkcs12 en utilisant la fonction SecPKCS12Import
  2. , utilisez la fonction SecIdentityCopyCertificate pour obtenir SecCertificateRef

et t Le repos (une initialisation de credential) est le même que dans ma question ... Je peux mettre ici plus de code si vous voulez. Notez qu'il y a un bug (http://openradar.appspot.com/7090030) dans le simulateur d'iphone, donc il n'est pas possible de travailler avec beaucoup de certifcates dans le simulateur.

1

Vous pouvez également rechercher l'identité dans le trousseau si vous stockez ces informations là:

+ (SecIdentityRef)dumpSecIdentityRef 
{ 
OSStatus err; 
CFArrayRef result; 
CFIndex  resultCount; 
CFIndex  resultIndex; 

result = NULL; 
err = SecItemCopyMatching((__bridge CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys: 
                 (__bridge id)kSecClassIdentity, 
                 kSecClass, kSecMatchLimitAll, 
                 kSecMatchLimit, kCFBooleanTrue, 
                 kSecReturnRef, kCFBooleanTrue, 
                 kSecReturnAttributes, nil], 
          (CFTypeRef *) &result); 

if ((result != NULL) && (err == noErr)) { 

    NSMutableArray *identitiesArray = [NSMutableArray new]; 

    resultCount = CFArrayGetCount(result); 
    for (resultIndex = 0; resultIndex < resultCount; resultIndex++) { 
     NSDictionary * thisResult; 
     thisResult = (__bridge NSDictionary *) CFArrayGetValueAtIndex(result, resultIndex); 
     NSLog(@"%@", (__bridge id)(result)); 
     [identitiesArray addObject:thisResult]; 
    } 

    CFRelease(result); 
    //TO DO - choose correct identity object from array. 
    SecIdentityRef myIdentity = (__bridge SecIdentityRef)([[identitiesArray objectAtIndex:0] valueForKey:@"v_Ref"]); 

    return myIdentity; 
} 
return nil; 
} 
Questions connexes