2012-04-20 12 views
6

Ricevo una richiesta di autenticazione da un server a cui la mia app sta tentando di connettersi, quindi ho implementato il metodo connection:didReceiveAuthenticationChallenge:. Devo inviare un SecCertificateRef e un SecIdentityRef. L'identità sta funzionando, ma il certificato deve essere inviato come NSArray e non riesco a capire come convertire un .Creazione di un SecCertificateRef per NSURLConnection Challenge di autenticazione

Questo è il mio metodo per la creazione dell'identità e del certificato:

// Returns an array containing the certificate 
- (CFArrayRef)getCertificate { 
    SecCertificateRef certificate = nil; 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"CertificateName" ofType:@"p12"]; 
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    certificate = SecCertificateCreateWithData(nil, inPKCS12Data); 
    SecCertificateRef certs[1] = { certificate }; 
    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL); 

    SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); 
    SecTrustRef myTrust; 

    OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust); 
    if (status == noErr) { 
    NSLog(@"No Err creating certificate"); 
    } else { 
    NSLog(@"Possible Err Creating certificate"); 
    } 
    return array; 
} 

// Returns the identity 
- (SecIdentityRef)getClientCertificate { 
    SecIdentityRef identityApp = nil; 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"CertificateName" ofType:@"p12"]; 
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    CFStringRef password = CFSTR("password"); 
    const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase }; 
    const void *values[] = { password }; 
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items); 
    CFRelease(options); 
    CFRelease(password); 
    if (securityError == errSecSuccess) { 
    NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items)); 
    CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); 
    identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 
    } else { 
    NSLog(@"Error opening Certificate."); 
    } 
    return identityApp; 
} 

E poi in connection:didReceiveAuthenticationChallenge: ho:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    if ([challenge previousFailureCount] == 0) { 
    SecIdentityRef identity = [self getClientCertificate]; // Go get a SecIdentityRef 
    CFArrayRef certs = [self getCertificate]; // Get an array of certificates 

    // Convert the CFArrayRef to a NSArray 
    NSArray *myArray = (__bridge NSArray *)certs; 

    // Create the NSURLCredential 
    NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:certs persistence:NSURLCredentialPersistenceNone]; 

    // Send 
    [challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge]; 
    } else { 
    // Failed 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 
} 

l'applicazione si blocca quando viene creato il NSURLCredential. Dopo un'ulteriore ispezione, ho concluso che quando converto lo CFArrayRef in un NSArray, i dati dello SecCertificateRef vengono persi e l'array contiene null causando un arresto anomalo.

Come è possibile inserire un SecCertificateRef in un NSArray? Ho perso un passaggio o sto sbagliando?

risposta

6

Ho finalmente trovato la risposta. Dovevo usare SecIdentityCopyCertificate(identity, &certificateRef); invece di SecCertificateCreateWithData(nil, inPKCS12Data); per creare il mio certificato.

Problemi correlati