2009-09-22 13 views
20

Estoy peleando con una autenticación de certificado de cliente. Cuando un servidor necesita una credencial (un certificado en este caso), este método se invoca desde NSURLConnection delegado:iPhone: autenticación de autenticación de cliente HTTPS

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

quiero cargar un certificado desde un archivo, llenar una credencial y ejecutar este método:

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

Pero no sé cómo inicializar (o relleno) un parámetro SecIdentityRef. Aquí está mi código que crea las credenciales:

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

¿Alguien sabe cómo solucionarlo? Gracias.


fin he encontrado la solución, pero un nuevo problema está aquí:

mi cliente no envía el certificado al servidor. Después de que el servidor solicita el certificado, la aplicación se ejecuta este método:

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

y llenar la credencial (como he mencionado anteriormente), pero la conexión termina con un error: NSURLErrorDomain -1206. Según los registros del servidor, la aplicación no envía el certificado del cliente.

¿Alguien tiene alguna experiencia con este comportamiento? ¿Debo verificar de alguna manera el certificado en la aplicación? O cualquier otra cosa para que funcione? Puedo proporcionar mi código actual si ayuda. Gracias por cualquier idea ...

Respuesta

0

Por supuesto, el problema era con el simulador de iPhone en Xcode :) Después de actualizar a la versión 3.1 comenzó a trabajar ...

+3

Sólo un consejo para hacer sus preguntas más legible: publicar preguntas que no haga como nuevas respuestas. Tiende a hacer que los hilos sean más difíciles de leer. Recuerde que su pregunta probablemente sea útil para otra persona y es importante que pueda ver su proceso y la respuesta final. ¡Gracias! – mtmurdock

4

utilizo estos pasos:

  1. extracto de SecIdentityRef del archivo de certificado pkcs12 usando la función SecPKCS12Import
  2. función de uso SecIdentityCopyCertificate llegar SecCertificateRef

yt El resto (una inicialización de credencial) es el mismo que en mi pregunta ... Puedo poner aquí más código si lo desea. Tenga en cuenta que hay un error (http://openradar.appspot.com/7090030) en el simulador de iphone, por lo que no es posible trabajar con muchos certifcates en el simulador.

1

También puede buscar la identidad en llavero si almacena esta información existe:

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