2009-09-22 14 views
20

Walczę z uwierzytelnianiem certyfikatu klienta. Gdy serwer potrzebuje poświadczeń (certyfikat w tym przypadku), metoda ta jest wywoływana z NSURLConnection Delegat:iPhone: uwierzytelnianie certyfikatu klienta HTTPS

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

Chcę załadować certyfikatu z pliku, wypełnij poświadczeń i uruchom tę metodę:

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

Ale nie wiem jak zainicjować (lub wypełnienie) do SecIdentityRef parametr. Oto mój kod, który tworzy poświadczenia:

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

Czy ktoś wie, jak go rozwiązać? Dzięki.


mam w końcu znaleźć rozwiązanie, ale nowy problem jest tutaj:

mój klient nie wysyła certyfikat do serwera. Po serwer prosi o certyfikacie, aplikacja uruchamia tą metodą:

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

i wypełnić poświadczeń (jak wspomniano powyżej), ale połączenie kończy się błędem: NSURLErrorDomain -1206. Zgodnie z dziennikami serwera certyfikat klienta nie jest wysyłany przez aplikację.

Czy ktoś ma jakiekolwiek doświadczenie w tym zachowaniu? Czy muszę w jakiś sposób zweryfikować certyfikat w aplikacji? Czy cokolwiek innego, żeby to zadziałało? Mogę podać mój obecny kod, jeśli to pomoże. Dzięki za wszelkie pomysły ...

Odpowiedz

0

Oczywiście problem był z symulatora iPhone w Xcode :) Po aktualizacji do wersji 3.1 zaczął pracować ...

+3

Just a wskazówka, aby twoje pytania bardziej czytelny: pytania Dont stanowiska nowych odpowiedzi. Sprawia, że ​​wątki są trudniejsze do odczytania. Pamiętaj, że twoje pytanie prawdopodobnie przyda się komuś innemu i ważne jest, aby zobaczył proces i ostateczną odpowiedź. Dzięki! – mtmurdock

4

używam kroki:

  1. ekstrakt SecIdentityRef z pliku certyfikatu pkcs12 użyciu
  2. funkcję użycie SecIdentityCopyCertificate funkcja SecPKCS12Import dostać SecCertificateRef

i t on reszta (inicjacja poświadczeń) jest taka sama jak w moim pytaniu ... Mogę tu umieścić więcej kodu, jeśli chcesz. Zauważ, że istnieje błąd (http://openradar.appspot.com/7090030) w symulatorze iphone, więc nie można pracować z wieloma certyfikatami w symulatorze.

1

Można też szukać tożsamości w pęku kluczy, jeśli przechowywać te informacje tam:

+ (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; 
} 
Powiązane problemy