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?