Estoy trabajando en una aplicación iOS5 que facilitará los pagos móviles entre dos usuarios. Como parte del proceso de pago, el remitente y el destinatario deben comunicarse con un servidor. El servidor requiere que ambas partes presenten sus identidades cuando se inicia una prueba de autenticación al conectarse.¿Cómo puedo importar un certificado por programación en el llavero de mi aplicación iOS y pasar la identidad a un servidor cuando sea necesario?
Actualmente, he no modificable el proceso de certificado mediante la utilización de los dos métodos siguientes en mi código:
NSURLConnection Delegado didReceiveAuthenticationChallenge
(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge *)challenge
{
NSLog(@"Authentication challenge");
// Load Certificate
NSString *path = [[NSBundle mainBundle] pathForResource:@"PKCS12" ofType:@"p12"];
NSData *p12data = [NSData dataWithContentsOfFile:path];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
C Método extractIdentityAndTrust
OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}
He probado este código varias veces y he tenido éxito. Ahora estoy tratando de seguir adelante y permitir que la identidad adecuada se almacene y luego se recupere del llavero de la aplicación. Mi objetivo es permitir a los usuarios importar sus archivos P12 a través de iTunes File Sharing o Dropbox y guardarlos en el llavero.
He consultado la documentación de Apple para Getting and Using Persistent Keychain References y no he podido averiguar cómo importar la identidad. Su código es un poco confuso para mí ya que usan variables/referencias no declaradas (específicamente la
&persistent_ref
variable). Si alguien pudiera ayudar a descifrarlo, sería muy apreciado.
TL; DR: ¿Cómo puedo guardar el contenido de un archivo P12 en mi llavero de IOS5 aplicación y recuperarlo más adelante a mano fuera de un método NSURLConnection didReceiveAuthenticationChallenge?
estoy teniendo el mismo problema con mi código de conexión SSL has encontrado una solución a ella? – Radu
hey, ¿pueden ayudarme? Tengo el error EXC_BAD en este punto. ¿Pueden orientar m? SecurityError = SecPKCS12Import (inP12data, options & items); –
@BhavikKama tal vez su referencia al archivo .p12 es incorrecta o utiliza un archivo de certificado no válido. –