Create SecCertificateRef for NSURLConnection Authentication Challenge

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]; // 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]; } } 

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?

+6
source share
1 answer

I finally found the answer. I should have used SecIdentityCopyCertificate(identity, &certificateRef); instead of SecCertificateCreateWithData(nil, inPKCS12Data); to create my certificate.

+6
source

Source: https://habr.com/ru/post/913670/


All Articles