NSURLCredentialStorage and client certificate authentication
Asked Answered
O

1

1

From what I see in the documentation of MPMoviewPlayerController, NSURLCredentialStorage can be set up as an alternative of NSURLConnection authentication challenges (this is useful for higher level classes that load resources from URLs but abstract the NSURLConnection away and don't provide a delegate for handling authentication challenges). This seems similar to installing a certificate in the browser and having it auto select the required certificate when a certain address demands it.

To test this out I have set up my own certificate authority, server certificate and client certificate (a .p12 file). I've set up an https server and successfully tested the client certificate using a browser, from a separate machine.

Now I need to have the certificate integrated in my iPhone app.

I've bundled up the p12 file and on application launch I do this:

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 is simply copied form the 'Certificate, Key, and Trust Services Tasks for iOS' documentation page (I just replaced the certificate password with my own).

From what I can tell the identity and the certificate are loaded nicely. If I print the NSURLCredential object in the console I get something like this: <NSURLCredential: 0x140ea0>: (null) (I can't tell if this is a good sign or not).

However when I execute setDefaultCredential the app crashes without giving much information.

The stacktrace 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

Looks to me like there something not set up in the credential.

Any ideas on how to solve this?

EDIT:

Just for testing I installed the certificate on the iPhone by opening the file from Mail. I can access the pages over https through Safari, but not through my app.

The only thing that works is if I open an NSURLConnection to any resource on the protected domain, respond to didReceiveAuthenticationChallenge (where I load up my credential exactly like in the code above, only I send it directly to NSURLAuthenticationChallenge's sender) and then access the stuff I really need using the higher level class.

Orthography answered 12/11, 2010 at 12:59 Comment(2)
I have a question: where was "extractIdentityAndTrust" declared? is that your method? or was it included from a library? I'm getting a linking error saying it cant find that method.Stormystorting
It's a method defined in my code. If you look up the name in the iOS documentation you'll find a sample code with that method.Orthography
O
4

It seems it's a known issue that NSURLCredentialStorage only works for username & password NSURLCredentials (certificates are not supported). Unfortunately the documentation mentions nothing about this.

Orthography answered 15/11, 2010 at 12:5 Comment(5)
Certificates dont work at all? Where did you read that? Could you provide a link?Stormystorting
Yes, please let us know where you got this info. Thanks!Neuropsychiatry
This is documented in the README file for the AdvancedURLConnections sample code. Current link (that Apple will break with their bi-weekly "break all documentation links" script): developer.apple.com/library/ios/#samplecode/…Neuropsychiatry
@Neuropsychiatry I get almost the same crash so I checked documentation to see and I didnt find anywhere that NSURCredentials doesnt support certificate.Nettlesome
@NulledPointer: sorry, I wish I'd left more details about what I meant by that. I can't figure out where that limitation was mentioned in the document I linked.Neuropsychiatry

© 2022 - 2024 — McMap. All rights reserved.