From what I see in the MPMoviewPlayerController documentation, NSURLCredentialStorage can be configured as an alternative to NSURLConnection authentication tasks (this is useful for higher-level classes that load resources from URLs but invalidate NSURLConnection and do not provide a delegate to handle authentication tasks). This is similar to installing a certificate in a browser and automatically detecting the required certificate when it needs a specific address.
To verify this, I set up my own certificate authority, server certificate, and client certificate (.p12 file). I installed the https server and successfully tested the client certificate using a browser from a separate machine.
Now I need to have a certificate integrated into my iPhone application.
I linked the p12 file and when starting the application:
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"clientside" ofType:@"p12"]; NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data; SecIdentityRef identity; SecTrustRef trust; extractIdentityAndTrust(inPKCS12Data, &identity, &trust); SecCertificateRef certificate = NULL; SecIdentityCopyCertificate (identity, &certificate); const void *certs[] = {certificate}; CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL); NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)certArray persistence:NSURLCredentialPersistencePermanent]; NSURLProtectionSpace *protectionSpace = [[NSURLProtectionSpace alloc] initWithHost: @"myhostname" port: 443 protocol: @"https" realm: nil authenticationMethod: NSURLAuthenticationMethodClientCertificate]; [[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential: credential forProtectionSpace: protectionSpace];
The extractIdentityAndTrust function was simply copied using the "Certificate, key and trust services for iOS" documentation page (I just replaced the certificate password with my own).
From what I can say that the identity and certificate are uploaded beautifully. If I print the NSURLCredential object in the console, I get something like this: <NSURLCredential: 0x140ea0>: (null) (I cannot tell if this is a good sign or not).
However, when setDefaultCredential is executed, the application crashes without providing a lot of information.
The stacktrace element looks something like this:
#0 0x350a41c8 in CFHash #1 0x3515180c in __CFBasicHashStandardHashKey #2 0x351534e4 in ___CFBasicHashFindBucket_Linear #3 0x350a4000 in CFBasicHashFindBucket #4 0x350a3ecc in CFDictionaryGetValue #5 0x344a0df2 in URLCredentialStorage::setDefaultCredentialForProtectionSpace #6 0x3446a5aa in CFURLCredentialStorageSetDefaultCredentialForProtectionSpace #7 0x339ec79e in -[NSURLCredentialStorage setDefaultCredential:forProtectionSpace:] #8 0x00002612 in -[AVPlayerExampleViewController awakeFromNib] at AVPlayerExampleViewController.m:84
It seems to me that there is something not configured in the credentials.
Any ideas on how to solve this?
EDIT:
Just for testing, I installed the certificate on the iPhone, opening the file from Mail. I can access pages via https through Safari, but not through my application.
The only thing that works: if I open NSURLConnection for any resource in a secure domain, respond to didReceiveAuthenticationChallenge (where I upload my credentials in the same way as in the above code, only I send it directly to the sender NSURLAuthenticationChallenge), and then access to the materials that I really need, using a higher level class.