2009-09-22 4 views
20

Ich kämpfe mit einer Client-Zertifikat-Authentifizierung. Wenn ein Server einen Berechtigungsnachweis (ein Zertifikat in diesem Fall) benötigt, wird diese Methode von NSURLConnection Delegierten aufgerufen:iPhone: HTTPS-Client-Zertifikat-Authentifizierung

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

ich ein Zertifikat aus einer Datei laden möge, einen Berechtigungsnachweis füllen und diese Methode ausführen:

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

Aber ich weiß nicht, wie zu initialisieren (oder ausfüllen) einen SecIdentityRef Parameter. Hier ist mein Code, der die Anmeldeinformationen erstellt:

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

Weiß jemand, wie man es löst? Vielen Dank.


Ich habe endlich die Lösung gefunden, aber ein neues Problem ist hier:

mein Kunde das Zertifikat an den Server nicht senden. Nachdem der Server für das Zertifikat fragt, wird die Anwendung dieses Verfahrens:

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

und I füllen den Berechtigungsnachweis (wie ich oben erwähnt), aber die Verbindung endet mit einem Fehler: NSURLErrorDomain -1206. Laut den Serverprotokollen wird das Clientzertifikat nicht von der Anwendung gesendet.

Hat jemand irgendwelche Erfahrung mit diesem Verhalten? Muss ich das Zertifikat in der Anwendung irgendwie überprüfen? Oder irgendetwas anderes, damit es funktioniert? Ich kann meinen aktuellen Code bereitstellen, wenn es hilft. Vielen Dank für alle Ideen ...

Antwort

0

Natürlich ist das Problem mit dem iPhone-Simulator in Xcode war :) Nach dem Update auf Version 3.1 fing es an ...

+3

Nur ein Tipp Ihre Fragen besser lesbar zu machen: dont Fragen stellen, als neue Antworten. Es neigt dazu, Threads schwieriger zu lesen. Denken Sie daran, dass Ihre Frage wahrscheinlich für jemand anderen nützlich ist und es wichtig ist, dass sie Ihren Prozess und die endgültige Antwort sehen können. Vielen Dank! – mtmurdock

4

ich diese Schritte zu arbeiten:

  1. Extrakt SecIdentityRef aus der pkcs12 Zertifikatsdatei mit SecPKCS12Import Funktion
  2. Verwendung SecIdentityCopyCertificate Funktion erhalten SecCertificateRef

und t Der Rest (eine Berechtigungsinitialisierung) ist der gleiche wie in meiner Frage ... Ich kann hier mehr Code einfügen, wenn du willst. Beachten Sie, dass es einen Fehler (http://openradar.appspot.com/7090030) im iPhone Simulator gibt, so dass es nicht möglich ist, mit vielen Zertifikaten im Simulator zu arbeiten.

1

Sie auch nach Identität in Schlüsselbund suchen können, wenn Sie diese Informationen speichern es:

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