team,
I have .net based REST service configured with 2-way SSL. In my iphone side, i have installed the server certificate in the device profiles and client certificate is bundled as application resource. Server certificate validation is working fine, but the client certificate authentication fails. Below is my code snippet
- (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 is failing with below mentioned error.
{
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.}";
}
Kindly help me how to reslove this.