I get an authentication request from the server my application is trying to connect to, so I applied the connection:didReceiveAuthenticationChallenge: method. I need to send SecCertificateRef and SecIdentityRef . Identity works, but the certificate needs to be sent as NSArray , and I cannot figure out how to convert CFArrayRef to NSArray .
This is my method of creating an identifier and certificate:
// 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; }
And then in connection:didReceiveAuthenticationChallenge: I have:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { if ([challenge previousFailureCount] == 0) { SecIdentityRef identity = [self getClientCertificate];
Application crashes while creating NSURLCredential . Upon further verification, I came to the conclusion that when converting CFArrayRef to NSArray data SecCertificateRef lost, and the array contains null, which causes a failure.
How can I place a SecCertificateRef in an NSArray ? Am I missing a step, or am I just doing it wrong?