|
// Mark: - Add delegate for URLSession |
|
let taskDelegateMonitor = TaskDelegateMonitor() |
|
let session = URLSession(configuration: .default, delegate: taskDelegateMonitor, delegateQueue: nil) |
|
let task = session.dataTask(with: request) { (data, response, error) in |
|
if let error, |
|
let urlError = error as? URLError |
|
{ |
|
switch urlError.code { |
|
case .serverCertificateUntrusted: |
|
break |
|
} |
|
} |
|
} |
|
|
|
// Mark: - Saving certificate |
|
let url = FileManager.default.temporaryDirectory.appendingPathComponent("certificate.crt") |
|
if let certText = TQManifest.shared.taskDelegateMonitor.currentServerCertificate { |
|
try? certText.write(to: url, atomically: true, encoding: .utf8) |
|
} |
|
let docController = UIDocumentPickerViewController(forExporting: [url]) |
|
present(docController, animated: true, completion: nil) |
|
|
|
// Mark: - Monitor |
|
class TaskDelegateMonitor: NSObject, URLSessionTaskDelegate { |
|
public private(set) var currentServerCertificate: String? |
|
private var host = "" |
|
|
|
public func urlSession( |
|
_ session: URLSession, |
|
task: URLSessionTask, |
|
didReceive challenge: URLAuthenticationChallenge, |
|
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) |
|
{ |
|
defer { |
|
completionHandler(.performDefaultHandling, nil) |
|
} |
|
|
|
let protectionSpace = challenge.protectionSpace |
|
guard let trust = protectionSpace.serverTrust, |
|
protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, |
|
host != protectionSpace.host |
|
else { return } |
|
|
|
guard let serverCertificate = SecTrustGetCertificateAtIndex(trust, 0) else { return } |
|
let serverCertificateData = SecCertificateCopyData(serverCertificate) |
|
let data = CFDataGetBytePtr(serverCertificateData) |
|
let size = CFDataGetLength(serverCertificateData) |
|
|
|
let certificate = Data(bytes: data!, count: size) |
|
var textContent = "-----BEGIN CERTIFICATE-----\n" |
|
textContent += certificate.base64EncodedString() + "\n" |
|
textContent += "-----END CERTIFICATE-----" |
|
currentServerCertificate = textContent |
|
host = protectionSpace.host |
|
} |
|
} |
Requirements for trusted certificates in iOS 13 and macOS 10.15 - https://support.apple.com/en-us/103769