summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2024-08-21 15:26:05 +0200
committerBug Magnet <marco.nikic@mullvad.net>2024-08-27 09:41:06 +0200
commit8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb (patch)
tree2a79e03c1fb157c41ce9b090fc1b6fcf0fd058ca
parent5dc31e7ac373636eb8a028c12f88b35171fe8123 (diff)
downloadmullvadvpn-8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb.tar.xz
mullvadvpn-8ff7f7ca9dbbd892f5a3cfc747188c26bfa916bb.zip
Modify the SSL Pinning logic to support conncheck as well
-rw-r--r--ios/MullvadREST/ApiHandlers/SSLPinningURLSessionDelegate.swift28
-rw-r--r--ios/MullvadVPN/SceneDelegate.swift2
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
)
),