Failed to authenticate using client certificate on iPhone

command,

I have a .net based REST service configured using two-way SSL. On my iphone side, I installed the server certificate in device profiles, and the client certificate as an application resource. Server certificate verification works fine, but client certificate authentication fails. Below is a snippet of code

- (void)connection:(NSURLConnection *) connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { NSLog(@"Authentication challenge with host: %@", challenge.protectionSpace.host); if([challenge previousFailureCount] == 0) { NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; NSString *authMethod = [protectionSpace authenticationMethod]; if(authMethod == NSURLAuthenticationMethodServerTrust ) { NSLog(@"Verifying The Trust"); [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[protectionSpace serverTrust]] forAuthenticationChallenge:challenge]; } else if(authMethod == NSURLAuthenticationMethodClientCertificate ) { NSLog(@"Trying Certificate"); // load cert NSString *thePath = [[NSBundle mainBundle] pathForResource:@"Myclientcertificate" ofType:@"pfx"]; NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data; OSStatus status = noErr; SecIdentityRef myIdentity; SecTrustRef myTrust; status = extractIdentityAndTrust( inPKCS12Data, &myIdentity, &myTrust); SecTrustResultType trustResult; if (status == noErr) { status = SecTrustEvaluate(myTrust, &trustResult); } SecCertificateRef myCertificate; SecIdentityCopyCertificate(myIdentity, &myCertificate); const void *certs[] = { myCertificate }; CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL); NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent]; [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; } } } - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { BOOL result; NSLog(@"canAuthenticateAgainstProtectionSpace: %@", protectionSpace.authenticationMethod); if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) { result= YES; } else if([protectionSpace authenticationMethod] == NSURLAuthenticationMethodClientCertificate) { result = YES; } return result; } OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data, SecIdentityRef *identity, SecTrustRef *trust){ OSStatus securityError = errSecSuccess; CFStringRef password = CFSTR("1234"); const void *keys[] = { kSecImportExportPassphrase }; const void *values[] = { password }; CFDictionaryRef optionsDictionary = CFDictionaryCreate( NULL, keys, values, 1, NULL, NULL); CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items); if (securityError == 0) { CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0); const void *tempIdentity = NULL; tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity); *identity = (SecIdentityRef)tempIdentity; const void *tempTrust = NULL; tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust); *trust = (SecTrustRef)tempTrust; } if (optionsDictionary) { CFRelease(optionsDictionary); } return securityError; } 

My connection does not work with the error below.

 { NSErrorFailingURLKey = "https://myIpdaddress/Service1.svc/test/random"; NSErrorFailingURLStringKey = "https://myIpdaddress/Service1.svc/test/random"; NSLocalizedDescription = "The server \U201cmyIpdaddress\U201d requires a client certificate."; NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1206 \"The server \U201cmyIpdaddress\U201d requires a client certificate.\" UserInfo=0x4b240b0 {NSErrorFailingURLKey=https://myIpdaddress/Service1.svc/test/random, NSErrorFailingURLStringKey=https://myIpdaddress/Service1.svc/test/random, NSLocalizedDescription=The server \U201cmyIpdaddress\U201d requires a client certificate.}"; } 

Please help me how to do this.

+6
source share
1 answer

I ran into the same problem.

The fix for me was to fix the Host HTTP header.

The one I used included the port and part of the path. As soon as I corrected this header to include only the host part of the URL, everything started to work.

I think the server rejected my identity when I had the wrong host header, and I think that the message “requires a client certificate” is a common response, which could also mean that the server did not accept the certificate presented.

+1
source

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


All Articles