Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS Mutual Authentication

I'm trying to implement mutual authentication in IOS 5 but i'm having troubles:

{NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1200 \"An SSL error has occurred and a secure connection to the server cannot be made.\" UserInfo=0x18d830 {NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFNetworkCFStreamSSLErrorOriginalValue=-9800, _kCFStreamPropertySSLClientCertificateState=0, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLStringKey=https://192.168.24.110:8081/t01.json, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0xceaa2d0>, NSErrorFailingURLKey=https://192.168.24.110:8081/t01.json}

I generated keys, certificates and pkcs12 for server (either self signed or with a fake CA I always got that problem) and client this way:

openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr

self-signed
openssl req -new -key ca.key -x509 -days 1095 -out ca.crt

CA signed
openssl x509 -req -days 365 -in client.csr -CA server.crt -CAkey server.key -CAcreateserial -out client.crt

CRT to PEM
openssl x509 -in client.crt -out client.der -outform DER
openssl x509 -in client.der -inform DER -out client.pem -outform PEM

PEM TO PKCS 12
openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12

The resulting client.p12 file works perfectly when I import it in the browser (FF15). So the problem is not locate in the previous steps.

IOS side I tried this example: http://vanjakom.wordpress.com/tag/nsurlconnection/

and this is what I wrote when I found that example not working:

// Returns an array containing the certificate
- (CFArrayRef)getCertificate:(SecIdentityRef) identity {
    SecCertificateRef certificate = nil;

    SecIdentityCopyCertificate(identity, &certificate);
    SecCertificateRef certs[1] = { certificate };

    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL);

    SecPolicyRef myPolicy   = SecPolicyCreateBasicX509();
    SecTrustRef myTrust;

    OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust);
    if (status == noErr) {
        NSLog(@"No Err creating certificate");
    } else {
        NSLog(@"Possible Err Creating certificate");
    }
    return array;
}

// Returns the identity
- (SecIdentityRef)getClientCertificate {
    SecIdentityRef identityApp = nil;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];
    NSString *myFilePath = [documentsDirectoryPath stringByAppendingPathComponent:@"file12.p12"]; 
    NSData *PKCS12Data = [NSData dataWithContentsOfFile:myFilePath];

    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
    CFStringRef password = CFSTR("password");
    const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase };
    const void *values[] = { password };
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
    CFRelease(options);
    CFRelease(password);
    if (securityError == errSecSuccess) {
        NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
        CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
        identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
    } else {
        NSLog(@"Error opening Certificate.");
    }

    return identityApp;
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge previousFailureCount] == 0) {
        SecIdentityRef identity = [self getClientCertificate];  // Go get a SecIdentityRef
        CFArrayRef certs = [self getCertificate:identity]; // Get an array of certificates
        // Convert the CFArrayRef to a NSArray
        NSArray *myArray = (__bridge NSArray *)certs;

        // Create the NSURLCredential
        NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent];

        // Send
        [challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];    
    } else {
        // Failed
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return YES;
}

In both cases I can't autheticate the client. Moreover I also installed the server.crt certificate on the device (iPhone/iPad) but I keep receiving "Error Domain=NSURLErrorDomain Code=-1200".

Any ideas? Thank you.

like image 406
lontra Avatar asked Sep 20 '12 13:09

lontra


People also ask

How do you get mutual authentication?

Mutual authentication stepsThe server also provides a session ID and a client certificate request. The server sends its digital certificate, along with its public key. The server sends a "Server Hello Done" message. The client verifies the server's certification information.

What is mutual authentication give an example?

Similarly, mutual authentication verifies both parties in a digital communications channel. For example, a client and a server using mutual authentication take steps to independently verify each other's identity, instead of only the client authenticating the server.

Is mTLS authentication or authorization?

MTLS is a form of client authentication and an extension of OAuth 2.0 that provides a mechanism of binding access tokens to a client certificate. It is one of many attempts at improving the security of Bearer Tokens by requiring the application using the token to authenticate itself.

Does mTLS provide authorization?

In practice, mTLS can identify and authorize the following: Devices onto a corporate network. Users into applications. Content delivery network (CDNs) or cloud security services to back-end web servers.


1 Answers

The code I wrote works perfectly, the problem was server side.

like image 118
lontra Avatar answered Sep 18 '22 06:09

lontra