2009-09-22 10 views
20

Sto combattendo con un'autenticazione del certificato client. Quando un server ha bisogno di una credenziale (un certificato in questo caso), questo metodo viene richiamato dal NSURLConnection delegato:iPhone: autenticazione CERT client HTTPS

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

voglio caricare un certificato da un file, riempire una credenziale ed eseguire questo metodo:

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

Ma io non so come inizializzare (o compili) un parametro SecIdentityRef. Ecco il mio codice che crea le credenziali:

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

qualcuno sa come risolverlo? Grazie.


ho finalmente trovato la soluzione, ma un nuovo problema è qui:

il mio cliente non invia il certificato al server. Dopo che il server richiede il certificato, l'applicazione viene eseguita questo metodo:

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

e riempire le credenziali (come ho detto sopra), ma la connessione si conclude con un errore: NSURLErrorDomain -1206. In base ai log del server, il certificato client non viene inviato dall'applicazione.

Qualcuno ha esperienza con questo comportamento? Devo in qualche modo verificare il certificato nell'applicazione? O qualcos'altro per farlo funzionare? Posso fornire il mio codice attuale se aiuta. Grazie per tutte le idee ...

risposta

0

Naturalmente il problema era con il simulatore di iPhone in Xcode :) Dopo l'aggiornamento alla versione 3.1 ha cominciato a lavorare ...

+3

Solo un consiglio per rendere le vostre domande più leggibile: domande Dont posto di nuove risposte. Tende a rendere i thread più difficili da leggere. Ricorda che la tua domanda sarà probabilmente utile a qualcun altro ed è importante che siano in grado di vedere il tuo processo e la risposta finale. Grazie! – mtmurdock

4

io uso questi passaggi:

  1. estratto SecIdentityRef dal file del certificato PKCS12 utilizzando la funzione SecPKCS12Import
  2. funzione d'uso SecIdentityCopyCertificate per ottenere SecCertificateRef

e t riposa (un'inizializzazione della credenziale) è la stessa della mia domanda ... Posso mettere qui più codice se vuoi. Notare che c'è un bug (http://openradar.appspot.com/7090030) nel simulatore iphone, quindi non è possibile lavorare con molti certificati nel simulatore.

1

È anche possibile cercare identità nel portachiavi se si memorizza queste informazioni ci:

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