2

I am trying to avoid using

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

I know you can store credentials in the

NSURLCredentialStorage * credentialStorage = [NSURLCredentialStorage sharedCredentialStorage];

I am storing my client cert in the credential storage using the following code

// Create Credential Store
NSURLCredentialStorage * credentialStore = [NSURLCredentialStorage sharedCredentialStorage];

// Create Configuration
NSURLSessionConfiguration * sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
[sessionConfiguration setURLCredentialStorage:credentialStore];

// Create Session
NSURLSession * session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:self.delegateOperationQueue];

// Create Credential
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(request.clientIdentity, &myCertificate);
const void * certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential * credential = [NSURLCredential credentialWithIdentity:request.clientIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];
CFRelease(certsArray);

// Create Protection Space
NSString * host = [urlRequest.URL host];
NSInteger port = [[urlRequest.URL port] integerValue];
NSString * protocol = [urlRequest.URL scheme];
NSURLProtectionSpace * protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:nil authenticationMethod:NSURLAuthenticationMethodClientCertificate];

// Add Credential to Shared Credentials
[credentialStorage setDefaultCredential:credential forProtectionSpace:protectionSpace];

Once I have added it here the Session/Task does not read it from the store. I implemented the

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

method and was able to recieve the challenge this way and I am able to get the default credential by doing the following

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler

{
    if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate)
    {
        NSString * host = [[challenge protectionSpace] host];
        NSInteger port = [[challenge protectionSpace] port];
        NSString * protocol = [[challenge protectionSpace] protocol];

        NSLog(@"%@ %ld %@",host,(long)port,protocol);

        // Get Credential
        NSURLCredential * credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:[challenge protectionSpace]];
    }

    // Defualt Handling
    completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,nil);
}

Which means to me that the credential is stored correctly but when I tell the completion handler to perform the default handling it fails and this is the error I get.

2014-11-03 11:09:02.368 PCSRegistrationServer Application[5555:1507600] CFNetwork SSLHandshake failed (-9824 -> -9829)

2014-11-03 11:09:02.459 PCSRegistrationServer Application[5555:1507600] NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9829)

Am I thinking about this wrong or is NSURLCredentialStorage not for NSURLAuthenticationMethodClientCertificate

Douglas Cobb
  • 193
  • 1
  • 9
  • Your error simply means that client certificate is wrong or not received at all. You may want to update your keychain and create an identity preference item with valid client certificate. If you have valid certificate in your keychain then you may try calling `[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];` in `didRecieveChallenge` ? – JamesWebbTelescopeAlien Mar 30 '15 at 23:03

0 Answers0