From be401c31743cfa0fac40ae23e6e9131065dee177 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Mon, 15 Aug 2022 20:53:16 +0100
Subject: [PATCH] Update cert pinning implementation

Use binary certificate (der)
---
 Sources/ReportingFeature/SendReport.swift | 44 ++++++++++++-----------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/Sources/ReportingFeature/SendReport.swift b/Sources/ReportingFeature/SendReport.swift
index e79214dd..acc24a0c 100644
--- a/Sources/ReportingFeature/SendReport.swift
+++ b/Sources/ReportingFeature/SendReport.swift
@@ -51,30 +51,32 @@ private final class SessionDelegate: NSObject, URLSessionDelegate {
         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
+        let authMethod = challenge.protectionSpace.authenticationMethod
+        guard authMethod == NSURLAuthenticationMethodServerTrust else {
+            return completionHandler(.cancelAuthenticationChallenge, nil)
         }
-        completionHandler(.cancelAuthenticationChallenge, nil)
-    }
-}
 
-private func handleServerTrustChallenge(_ serverTrust: SecTrust) -> Bool {
-    guard let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
-        return false
-    }
+        guard let serverTrust = challenge.protectionSpace.serverTrust else {
+            return completionHandler(.cancelAuthenticationChallenge, nil)
+        }
 
-    let serverCertCFData = SecCertificateCopyData(serverCert)
-    let serverCertNSData = NSData(
-        bytes: CFDataGetBytePtr(serverCertCFData),
-        length: CFDataGetLength(serverCertCFData)
-    )
+        guard let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
+            return completionHandler(.cancelAuthenticationChallenge, nil)
+        }
+
+        let serverCertCFData = SecCertificateCopyData(serverCert)
+        let serverCertData = Data(
+            bytes: CFDataGetBytePtr(serverCertCFData),
+            count: CFDataGetLength(serverCertCFData)
+        )
 
-    let localCertPath = Bundle.module.path(forResource: "report_cert", ofType: "crt")!
-    let localCertNSData = NSData(contentsOfFile: localCertPath)!
+        let localCertURL = Bundle.module.url(forResource: "report_cert", withExtension: "der")!
+        let localCertData = try! Data(contentsOf: localCertURL)
 
-    return serverCertNSData.isEqual(to: localCertNSData as Data)
+        guard serverCertData == localCertData else {
+            return completionHandler(.cancelAuthenticationChallenge, nil)
+        }
+
+        completionHandler(.useCredential, URLCredential(trust: serverTrust))
+    }
 }
-- 
GitLab