0

I am trying to achieve client certificate authentication using URLSession but SSL Handshake fails.

Here is my code for authentication -

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
        NSLog(@"didReceiveAuthenticationChallenge - %@", challenge.protectionSpace);
        
        if ( [challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] )
        {
            SecTrustRef secTrustRef = challenge.protectionSpace.serverTrust;
            if (secTrustRef != NULL)
            {
                SecTrustResultType result;
                OSErr er = SecTrustEvaluate(secTrustRef, &result);
                if (er != noErr){
                    NSLog(@"error");
                }
                
                switch ( result )
                {
                    case kSecTrustResultProceed:
                        NSLog(@"kSecTrustResultProceed");
                        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
                        break;
                    case kSecTrustResultUnspecified: // called 2nd
                        NSLog(@"kSecTrustResultUnspecified");
                        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, [NSURLCredential credentialForTrust:secTrustRef]);
                        break;
                    case kSecTrustResultRecoverableTrustFailure:
                        NSLog(@"kSecTrustResultRecoverableTrustFailure");
                        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, [NSURLCredential credentialForTrust:secTrustRef]);
                        break;
                }
            }
            
            return;
        } else if ( [challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate] )
        {
            
            NSString *p12Path = [[NSBundle mainBundle] pathForResource:@“p12filepath" ofType:@"p12"];
            NSData *p12Data = [[NSData alloc] initWithContentsOfFile:p12Path];
            
            CFStringRef password = CFSTR(“password");
            const void *keys[] = { kSecImportExportPassphrase };
            const void *values[] = { password };
            CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
            CFArrayRef p12Items;
            
            OSStatus result = SecPKCS12Import((__bridge CFDataRef)p12Data, optionsDictionary, &p12Items);
            
            if(result == noErr) {
                SecCertificateRef certRef;
                
                CFDictionaryRef identityDict = CFArrayGetValueAtIndex(p12Items, 0);
     
                SecIdentityRef identityApp =(SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);
                SecIdentityCopyCertificate(identityApp, &certRef);
        
                SecCertificateRef certArray[1] = { certRef };
                CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
                
                NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identityApp certificates:(__bridge NSArray
    *)myCerts persistence:NSURLCredentialPersistencePermanent];
                completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
                NSLog(@"myCerts : %@",myCerts);
                
                CFRelease(myCerts);
                CFRelease(certRef);
    
        
            }
        } else if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodDefault || [[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodNTLM) {
            
            NSLog(@"BASIC AUTHENTICATION");
        } else {
            //If everything fails, we cancel the challenge.
            [[challenge sender] cancelAuthenticationChallenge:challenge];
        } 
    }

The error which i am receiving is -

[BoringSSL] Function nw_protocol_boringssl_input_finished: line 1436 Peer disconnected during the middle of a handshake. Sending errSSLFatalAlert(-9802) alert

TIC TCP Conn Failed [1:0x60c00017f380]: 3:-9802 Err(-9802)

2018-08-24 15:32:35.060020+0530 TestProject[20549:17847062] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

Task .<1> HTTP load failed (error code: -1200 [3:-9802])
Task .<1> finished with error - code: -1200

I have configured info.plist correctly as mentioned here - https://stackoverflow.com/a/32756356/10269423

Arnab
  • 4,216
  • 2
  • 28
  • 50

1 Answers1

0

Have you tried to use

let credential = URLCredential.init(trust: trust!)
completionHandler(URLSession.AuthChallengeDisposition.useCredential, credential)

instead of

completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
Stefan Becker
  • 5,695
  • 9
  • 20
  • 30