I guess by using .p12 certificate, you are referring to establishing a mutual authentication between the client and the server. Basically, you have to go through the following steps (objective-c):
- Create security objects required to authenticate the server (verify its signature against the root CA signature) and authenticate the client (provide the client certificate to the server to verify its signature as well). Load a .cer file of the CA and a .p12 file of the client.
- Define the URL resource you want to retrieve and create NSURLConnection
- Specify the authentication methods you want to handle (using NSURLConnectionDelegate callbacks)
- Handle the authentication challenge (using NSURLConnectionDelegate callbacks)
Load Cert files (root CA Cert of the server + client key and certificate)
rootCertRef contains the CA Certificate (root certificate of the CA that signed the server certificate)
identity (SecIdentityRef) contains the client key and certificate required to authenticate the client with the server.
NSData *rootCertData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”rootCert” ofType:@”cer”]];
SecCertificateRef rootCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@“clientCert" ofType:@"p12"]];
NSArray *item = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@“password", kSecImportExportPassphrase, nil];
SecPKCS12Import((CFDataRef) p12Data , (CFDictionaryRef)dict, (CFArrayRef *)item);
SecIdentityRef identity = (SecIdentityRef)[[item objectAtIndex:0] objectForKey:(id)kSecImportItemIdentity];
Configure the URL (you already did it)
// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
Create NSURLConnection >> set the delegate to self that must implement NSURLConnectionDelegate to be able to do customer authentication
// Create url connection and fire request asynchronously
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Enable server and client authentication in callback canAuthenticateAgainstProtectionSpace
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
return YES;
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate])
return YES;
return NO;
}
Perform the mutual authentication requested by the server
-(void) connection:didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
//Authenticate the server
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { // Verify method
SecTrustRef trust = [[challenge protectionSpace] serverTrust]; // Create trust object
NSArray *trustArray = [NSArray arrayWithObjects:rootCertRef, nil]; // Add as many certificates as needed
SecTrustSetAnchorCertificates(trust, (CFArrayRef) trustArray ); // Set trust anchors
SecTrustResultType trustResult; // Store trust result in this
SecTrustEvaluate(trust, trustResult); // Evaluate server trust
if(trust_result == kSecTrustResultUnspecified) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
// handle error;
}
//Send client identity to server for client authentication
if([[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}