diff --git a/Sources/ReportingFeature/SendReport.swift b/Sources/ReportingFeature/SendReport.swift index 41c6f159a304e184aa79b63b0ba85faf345724ed..e79214ddd3c3a0ba0baa0b7e7c6ae310bdcab3c2 100644 --- a/Sources/ReportingFeature/SendReport.swift +++ b/Sources/ReportingFeature/SendReport.swift @@ -45,6 +45,36 @@ extension SendReport { ) } -private class SessionDelegate: NSObject, URLSessionDelegate { - // TODO: handle TLS +private final class SessionDelegate: NSObject, URLSessionDelegate { + func urlSession( + _ session: URLSession, + didReceive challenge: URLAuthenticationChallenge, + completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void + ) { + let authenticationMethod = challenge.protectionSpace.authenticationMethod + if authenticationMethod == NSURLAuthenticationMethodServerTrust, + let serverTrust = challenge.protectionSpace.serverTrust, + handleServerTrustChallenge(serverTrust) { + completionHandler(.useCredential, URLCredential(trust: serverTrust)) + return + } + completionHandler(.cancelAuthenticationChallenge, nil) + } +} + +private func handleServerTrustChallenge(_ serverTrust: SecTrust) -> Bool { + guard let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0) else { + return false + } + + let serverCertCFData = SecCertificateCopyData(serverCert) + let serverCertNSData = NSData( + bytes: CFDataGetBytePtr(serverCertCFData), + length: CFDataGetLength(serverCertCFData) + ) + + let localCertPath = Bundle.module.path(forResource: "report_cert", ofType: "crt")! + let localCertNSData = NSData(contentsOfFile: localCertPath)! + + return serverCertNSData.isEqual(to: localCertNSData as Data) }