Skip to content

Instantly share code, notes, and snippets.

@mkormendy
Forked from ronaldmannak/NetworkManager.swift
Created January 28, 2019 06:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkormendy/16989138a3d18983e528d6f8402432f9 to your computer and use it in GitHub Desktop.
Save mkormendy/16989138a3d18983e528d6f8402432f9 to your computer and use it in GitHub Desktop.
Proof of concept for Connecting to the BMW Connect server using SSL certificate pinning. Assumes you have copied GlobalSignOrganizationValidationCA-SHA256-G2.cer from the Connected Drive iOS app bundle
import Foundation
final class NetworkManager: NSObject, URLSessionDelegate {
func login() {
var request = URLRequest(url: URL(string: "https://b2vapi.bmwgroup.com/webapi/oauth/token/")!)
request.addValue("Content-Type", forHTTPHeaderField: "application/json")
request.httpMethod = "GET"
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
session.dataTask(with: request) {data, response, err in
print("=========================DATA===============================")
if data != nil {
print(data!)
}
print("=========================RESPONSE===========================")
if response != nil {
print(response!)
}
print("=========================ERR================================")
if err != nil {
print(err!)
}
}.resume()
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
if let serverTrust = challenge.protectionSpace.serverTrust {
var secresult = SecTrustResultType.invalid
let status = SecTrustEvaluate(serverTrust, &secresult)
if(errSecSuccess == status) {
let certificateIndex = 1 // Second certificate is the one we need
if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, certificateIndex) {
// Is there a better way to compare certificates other than comparing NSData?
let serverCertificateData = SecCertificateCopyData(serverCertificate)
let serverCertData = CFDataGetBytePtr(serverCertificateData);
let serverCertSize = CFDataGetLength(serverCertificateData);
let serverCertData2 = NSData(bytes: serverCertData, length: serverCertSize)
let certificateFileName = "GlobalSignOrganizationValidationCA-SHA256-G2"
let file = Bundle.main.path(forResource: certificateFileName, ofType: "cer")!
let localCertificateData = NSData(contentsOfFile: file)!
if serverCertData2.isEqual(to: localCertificateData as Data) {
// Pinning succeeded
completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust))
return
}
}
}
}
}
// Pinning failed
completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment