From 55ea15418bdb065f9a604d307adbb49572a98419 Mon Sep 17 00:00:00 2001 From: Artur Savitskiy Date: Tue, 4 Jun 2024 10:46:10 +0200 Subject: [PATCH] add debug mode for SSL --- Befund/Core/Https/Request.swift | 20 ++-- Befund/Core/Https/RequestAsync.swift | 138 +++++++++++++++++---------- 2 files changed, 94 insertions(+), 64 deletions(-) diff --git a/Befund/Core/Https/Request.swift b/Befund/Core/Https/Request.swift index 3bb84ae..0a510d5 100644 --- a/Befund/Core/Https/Request.swift +++ b/Befund/Core/Https/Request.swift @@ -350,22 +350,16 @@ extension Core } } } -/* - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) - { + + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { #if DEBUG - completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) + // Accept all certificates + let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!) + completionHandler(.useCredential, urlCredential) #else - if(challenge.protectionSpace.host.contains("pba-simulator.patientenbefundapp.labor-limbach-hannover.de")) - { - completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!)) - } - else - { - completionHandler(.performDefaultHandling, nil) - } + completionHandler(.performDefaultHandling, nil) #endif - }*/ + } } /** diff --git a/Befund/Core/Https/RequestAsync.swift b/Befund/Core/Https/RequestAsync.swift index d1326fc..ad90f43 100644 --- a/Befund/Core/Https/RequestAsync.swift +++ b/Befund/Core/Https/RequestAsync.swift @@ -11,8 +11,35 @@ import Combine import CryptoKit +extension SecTrust { + + var isSelfSigned: Bool? { + guard SecTrustGetCertificateCount(self) == 1 else { + return false + } + guard let cert = SecTrustGetCertificateAtIndex(self, 0) else { + return nil + } + return cert.isSelfSigned + } +} + +extension SecCertificate { + + var isSelfSigned: Bool? { + guard + let subject = SecCertificateCopyNormalizedSubjectSequence(self), + let issuer = SecCertificateCopyNormalizedIssuerSequence(self) + else { + return nil + } + return subject == issuer + } +} + extension Core { + enum RequestError: Error { case HANDLED_ERROR(msg: String) @@ -66,7 +93,7 @@ extension Core get async throws { if (_publicKey == nil) { - _publicKey = try await postRequest.getPublicKey(host: host, controller: controller, action: action, _keyPair: keyPair) + _publicKey = try await postRequest.getPublicKey(host: host, _keyPair: keyPair) } return _publicKey } @@ -80,11 +107,20 @@ extension Core public var response: Core.Models.Response.EncryptedResponse? { get async throws { - let encryptedRequest = Core.Models.Request.EncryptedRequest(descriptor: descriptor, contentObject: contentObject, requestType: requestType, key: try await sharedKey!) + let _shared = try await sharedKey + if(_shared != nil) + { + let encryptedRequest = Core.Models.Request.EncryptedRequest(descriptor: descriptor, contentObject: contentObject, requestType: requestType, key: _shared!) - let encryptedResponse = try await postRequest.getEncryptedResponse(host: host, controller: controller, action: action, _request: encryptedRequest, serverPublicKey: publicKey, _keyPair: keyPair) - - return encryptedResponse + let encryptedResponse = try await postRequest.getEncryptedResponse(host: host, controller: controller, action: action, _request: encryptedRequest, serverPublicKey: publicKey, _keyPair: keyPair) + + return encryptedResponse + + } + else + { + return nil + } } } @@ -118,17 +154,23 @@ extension Core */ func getEncryptedResponse(host: Https.Servers, controller: String, action: String, _request: Core.Models.Request.EncryptedRequest, serverPublicKey: Core.Models.Response.PublicKey?, _keyPair: Core.Security.Curve25519.KeyPair? = nil) async throws -> Core.Models.Response.EncryptedResponse { + var (data,response) : (Data, URLResponse) + let keyPair = PrepareKeyPair(_keyPair: _keyPair) do - { - let keyPair = PrepareKeyPair(_keyPair: _keyPair) - + { let request = try PrepareURLRequest(host: host, controller: controller, action: action, _request: _request, keyPair: keyPair) - let (data,response) = try await URLSession.shared.data(for: request) - - let httpR = response as? HTTPURLResponse - if (httpR != nil) - { + let s = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil) + (data,response) = try await s.data(for: request) + } + catch + { + throw RequestError.UNEXPECTED_ERROR(msg: error.localizedDescription) + } + + let httpR = response as? HTTPURLResponse + if (httpR != nil) + { if (httpR?.statusCode == 429) { AppDelegate.Session.Maintenance = false @@ -162,34 +204,35 @@ extension Core } } } - } - else - { - throw RequestError.HANDLED_ERROR(msg: Core.Lang.Get(key: "ERROR_INVALID_RESPONSE")) - } + } + else + { + throw RequestError.HANDLED_ERROR(msg: Core.Lang.Get(key: "ERROR_INVALID_RESPONSE")) + } + } + + @MainActor + func getPublicKey(host: Https.Servers, _keyPair: Core.Security.Curve25519.KeyPair? = nil) async throws -> Core.Models.Response.PublicKey + { + var (data,response) : (Data, URLResponse) + do + { + let keyPair = PrepareKeyPair(_keyPair: _keyPair) + + let request = try PrepareURLRequest(host: host, controller: "exchange", action: "key", _request: nil, keyPair: keyPair) + + let s = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil) + (data,response) = try await s.data(for: request) } catch { throw RequestError.UNEXPECTED_ERROR(msg: error.localizedDescription) } - } - - @MainActor - func getPublicKey(host: Https.Servers, controller: String, action: String, _keyPair: Core.Security.Curve25519.KeyPair? = nil) async throws -> Core.Models.Response.PublicKey - { - do + + let httpR = response as? HTTPURLResponse + if(httpR != nil) { - let keyPair = PrepareKeyPair(_keyPair: _keyPair) - - let request = try PrepareURLRequest(host: host, controller: controller, action: action, _request: nil, keyPair: keyPair) - - let s = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil) - let (data,response) = try await s.data(for: request) - - let httpR = response as? HTTPURLResponse - if(httpR != nil) - { if (httpR!.statusCode == 429) { @@ -216,30 +259,23 @@ extension Core return publicKey } } - } - else - { - throw RequestError.HANDLED_ERROR(msg: Core.Lang.Get(key: "ERROR_INVALID_RESPONSE")) - } - } - catch + else { - throw RequestError.UNEXPECTED_ERROR(msg: error.localizedDescription) + throw RequestError.HANDLED_ERROR(msg: Core.Lang.Get(key: "ERROR_INVALID_RESPONSE")) } + } - - nonisolated public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { - let trust = challenge.protectionSpace.serverTrust! - completionHandler(.useCredential, URLCredential(trust:trust)) - return - } - completionHandler(.cancelAuthenticationChallenge, nil) +#if DEBUG + // Accept all certificates + let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!) + completionHandler(.useCredential, urlCredential) +#else + completionHandler(.performDefaultHandling, nil) +#endif } - private func PrepareKeyPair(_keyPair: Core.Security.Curve25519.KeyPair? = nil) -> Core.Security.Curve25519.KeyPair {