The web service I want to consume requires a client certificate. How can I send my certificate to it?
To further elaborate I don\'t understand how to create the
In order to respond to the authentication challenge you need to extract the identity from your client certificate.
struct IdentityAndTrust {
var identityRef:SecIdentityRef
var trust:SecTrustRef
var certArray:NSArray
}
func extractIdentity(certData:NSData, certPassword:String) -> IdentityAndTrust {
var identityAndTrust:IdentityAndTrust!
var securityError:OSStatus = errSecSuccess
var items:Unmanaged?
let certOptions:CFDictionary = [ kSecImportExportPassphrase.takeRetainedValue() as String: certPassword ];
// import certificate to read its entries
securityError = SecPKCS12Import(certData, certOptions, &items);
if securityError == errSecSuccess {
let certItems:CFArray = items?.takeUnretainedValue() as CFArray!;
let certItemsArray:Array = certItems as Array
let dict:AnyObject? = certItemsArray.first;
if let certEntry:Dictionary = dict as? Dictionary {
// grab the identity
let identityPointer:AnyObject? = certEntry["identity"];
let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;
// grab the trust
let trustPointer:AnyObject? = certEntry["trust"];
let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
// grab the certificate chain
var certRef:Unmanaged?
SecIdentityCopyCertificate(secIdentityRef, &certRef);
let certArray:NSMutableArray = NSMutableArray();
certArray.addObject(certRef?.takeRetainedValue() as SecCertificateRef!);
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: certArray);
}
}
return identityAndTrust;
}
In NSURLSessionDelegate
respond to the authentication challenge like this:
public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
let bundle:NSBundle = NSBundle(forClass: self.dynamicType);
let bundleCertPath:NSString = bundle.pathForResource("clientCertificateName", ofType: "p12")!;
let certData:NSData = NSData(contentsOfFile: bundleCertPath as String)!;
let identityAndTrust:IdentityAndTrust = self.certificateHelper.extractIdentity(certData, certPassword: "C00lp@assword");
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate {
let urlCredential:NSURLCredential = NSURLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as [AnyObject],
persistence: NSURLCredentialPersistence.ForSession);
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential);
} else {
// nothing here but us chickens
}
}