diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2024-08-21 15:26:05 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2024-08-27 09:41:06 +0200 |
| commit | 8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb (patch) | |
| tree | 2a79e03c1fb157c41ce9b090fc1b6fcf0fd058ca | |
| parent | 5dc31e7ac373636eb8a028c12f88b35171fe8123 (diff) | |
| download | mullvadvpn-8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb.tar.xz mullvadvpn-8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb.zip | |
Modify the SSL Pinning logic to support conncheck as well
| -rw-r--r-- | ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift | 28 | ||||
| -rw-r--r-- | ios/MullvadVPN/SceneDelegate.swift | 2 |
2 files changed, 23 insertions, 7 deletions
diff --git a/ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift b/ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift index 6ab457fd49..2d0d1ca406 100644 --- a/ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift +++ b/ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift @@ -8,6 +8,7 @@ import Foundation import MullvadLogging +import Network import Security final class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate { @@ -29,17 +30,32 @@ final class SSLPinningURLSessionDelegate: NSObject, URLSessionDelegate { completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void ) { if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, - let serverTrust = challenge.protectionSpace.serverTrust, - verifyServerTrust(serverTrust) { - completionHandler(.useCredential, URLCredential(trust: serverTrust)) - } else { - completionHandler(.rejectProtectionSpace, nil) + let serverTrust = challenge.protectionSpace.serverTrust { + /// If a request is going through a local shadowsocks proxy, the host would be a localhost address,` + /// which would not appear in the list of valid host names in the root certificate. + /// The same goes for direct connections to the API, the host would be the IP address of the endpoint. + /// Certificates, cannot be signed for IP addresses, in such case, specify that the host name is `defaultAPIHostname` + var hostName = challenge.protectionSpace.host + let overridenHostnames = [ + "\(IPv4Address.loopback)", + "\(IPv6Address.loopback)", + "\(REST.defaultAPIEndpoint.ip)", + ] + if overridenHostnames.contains(hostName) { + hostName = sslHostname + } + + if verifyServerTrust(serverTrust, for: hostName) { + completionHandler(.useCredential, URLCredential(trust: serverTrust)) + return + } } + completionHandler(.rejectProtectionSpace, nil) } // MARK: - Private - private func verifyServerTrust(_ serverTrust: SecTrust) -> Bool { + private func verifyServerTrust(_ serverTrust: SecTrust, for sslHostname: String) -> Bool { var secResult: OSStatus // Set SSL policy diff --git a/ios/MullvadVPN/SceneDelegate.swift b/ios/MullvadVPN/SceneDelegate.swift index d70b631b37..618555f5fe 100644 --- a/ios/MullvadVPN/SceneDelegate.swift +++ b/ios/MullvadVPN/SceneDelegate.swift @@ -74,7 +74,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, SettingsMigrationUIHand accountsProxy: appDelegate.accountsProxy, outgoingConnectionService: OutgoingConnectionService( outgoingConnectionProxy: OutgoingConnectionProxy( - urlSession: URLSession(configuration: .ephemeral), + urlSession: REST.makeURLSession(), hostname: ApplicationConfiguration.hostName ) ), |
