Created
September 9, 2017 10:18
-
-
Save 29satnam/a47d9b569204df7fcec4160027a4a0b8 to your computer and use it in GitHub Desktop.
SSL Pinning Swift 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Step 1: class ViewController: ..... URLSessionDelegate, URLSessionTaskDelegate | |
// Step 2: Usage | |
if let url = NSURL(string: "https://example.com") { | |
let session = URLSession( | |
configuration: URLSessionConfiguration.ephemeral, | |
delegate: NSURLSessionPinningDelegate(), | |
delegateQueue: nil) | |
let task = session.dataTask(with: url as URL, completionHandler: { (data, response, error) -> Void in | |
if error != nil { | |
print("error: \(error!.localizedDescription): \(error!)") | |
} else if data != nil { | |
if let str = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) { | |
print("Received data:\n\(str)") | |
} | |
else { | |
print("Unable to convert data to text") | |
} | |
} | |
}) | |
task.resume() | |
} | |
else { | |
print("Unable to create NSURL") | |
} | |
//Step 3: Add following code to a Swift file | |
import ..... | |
import Security | |
class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate { | |
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) { | |
// Adapted from OWASP https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#iOS | |
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 cert1 = NSData(bytes: data, length: size) | |
let file_der = Bundle.main.path(forResource: "example.com", ofType: "der") | |
if let file = file_der { | |
if let cert2 = NSData(contentsOfFile: file) { | |
if cert1.isEqual(to: cert2 as Data) { | |
completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust)) | |
return | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
// Pinning failed | |
completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil) | |
} | |
} | |
// Step 4: Run following command in terminal | |
openssl s_client -connect example.com:443 -showcerts < /dev/null | openssl x509 -outform DER > example.com.der | |
// Step 5: drop output der file to your project | |
example.com.dir -> project |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment