Howto add certificate pinning to a NSURLSession in Swift?
The OWASP website contains only an example for Objective-C and NSURLConnection.
You can try this.
import Foundation
import Security
class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate {
let certFileName = "name-of-cert-file"
let certFileType = "cer"
func urlSession(_ session: URLSession,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
if let serverTrust = challenge.protectionSpace.serverTrust {
var secresult = SecTrustResultType.invalid
let status = SecTrustEvaluate(serverTrust, &secresult)
if(errSecSuccess == status) {
if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {
let serverCertificateData = SecCertificateCopyData(serverCertificate)
let data = CFDataGetBytePtr(serverCertificateData);
let size = CFDataGetLength(serverCertificateData);
let certificateOne = NSData(bytes: data, length: size)
let filePath = Bundle.main.path(forResource: self.certFileName,
ofType: self.certFileType)
if let file = filePath {
if let certificateTwo = NSData(contentsOfFile: file) {
if certificateOne.isEqual(to: certificateTwo as Data) {
completionHandler(URLSession.AuthChallengeDisposition.useCredential,
URLCredential(trust:serverTrust))
return
}
}
}
}
}
}
}
// Pinning failed
completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
}
}
Source: https://www.steveclarkapps.com/using-certificate-pinning-xcode/