Take a cache URL in SessionProxy to store PEMs
This commit is contained in:
parent
3fd0329736
commit
197d29042c
|
@ -83,13 +83,15 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
|
||||||
private let prngSeedLength = 64
|
private let prngSeedLength = 64
|
||||||
|
|
||||||
private var cachesURL: URL {
|
private var cachesURL: URL {
|
||||||
return URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0])
|
guard let appGroup = appGroup else {
|
||||||
|
fatalError("Accessing cachesURL before parsing app group")
|
||||||
|
}
|
||||||
|
guard let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
|
||||||
|
fatalError("No access to app group: \(appGroup)")
|
||||||
|
}
|
||||||
|
return containerURL.appendingPathComponent("Library/Caches/")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func temporaryURL(forKey key: String) -> URL {
|
|
||||||
return cachesURL.appendingPathComponent("\(key).pem")
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Tunnel configuration
|
// MARK: Tunnel configuration
|
||||||
|
|
||||||
private var appGroup: String!
|
private var appGroup: String!
|
||||||
|
@ -181,42 +183,6 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
|
||||||
completionHandler(ProviderConfigurationError.prngInitialization)
|
completionHandler(ProviderConfigurationError.prngInitialization)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// let caPath: String
|
|
||||||
// let clientCertificatePath: String?
|
|
||||||
// let clientKeyPath: String?
|
|
||||||
// do {
|
|
||||||
// let url = temporaryURL(forKey: Configuration.Keys.ca)
|
|
||||||
// try cfg.ca.write(to: url)
|
|
||||||
// caPath = url.path
|
|
||||||
// } catch {
|
|
||||||
// completionHandler(ProviderConfigurationError.certificateSerialization)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if let clientCertificate = cfg.clientCertificate {
|
|
||||||
// do {
|
|
||||||
// let url = temporaryURL(forKey: Configuration.Keys.clientCertificate)
|
|
||||||
// try clientCertificate.write(to: url)
|
|
||||||
// clientCertificatePath = url.path
|
|
||||||
// } catch {
|
|
||||||
// completionHandler(ProviderConfigurationError.certificateSerialization)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// clientCertificatePath = nil
|
|
||||||
// }
|
|
||||||
// if let clientKey = cfg.clientKey {
|
|
||||||
// do {
|
|
||||||
// let url = temporaryURL(forKey: Configuration.Keys.clientKey)
|
|
||||||
// try clientKey.write(to: url)
|
|
||||||
// clientKeyPath = url.path
|
|
||||||
// } catch {
|
|
||||||
// completionHandler(ProviderConfigurationError.certificateSerialization)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// clientKeyPath = nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
cfg.print(appVersion: appVersion)
|
cfg.print(appVersion: appVersion)
|
||||||
|
|
||||||
|
@ -239,7 +205,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
|
||||||
|
|
||||||
let proxy: SessionProxy
|
let proxy: SessionProxy
|
||||||
do {
|
do {
|
||||||
proxy = try SessionProxy(queue: tunnelQueue, configuration: sessionConfiguration.build())
|
proxy = try SessionProxy(queue: tunnelQueue, configuration: sessionConfiguration.build(), cachesURL: cachesURL)
|
||||||
} catch let e {
|
} catch let e {
|
||||||
completionHandler(e)
|
completionHandler(e)
|
||||||
return
|
return
|
||||||
|
@ -382,10 +348,6 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
|
||||||
}
|
}
|
||||||
// stopped externally, unrecoverable
|
// stopped externally, unrecoverable
|
||||||
else {
|
else {
|
||||||
let fm = FileManager.default
|
|
||||||
for key in [Configuration.Keys.ca, Configuration.Keys.clientCertificate, Configuration.Keys.clientKey] {
|
|
||||||
try? fm.removeItem(at: temporaryURL(forKey: key))
|
|
||||||
}
|
|
||||||
cancelTunnelWithError(error)
|
cancelTunnelWithError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,14 @@ public class SessionProxy {
|
||||||
case reconnect
|
case reconnect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct Caches {
|
||||||
|
static let ca = "ca.pem"
|
||||||
|
|
||||||
|
static let clientCertificate = "cert.pem"
|
||||||
|
|
||||||
|
static let clientKey = "key.pem"
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Configuration
|
// MARK: Configuration
|
||||||
|
|
||||||
private let configuration: Configuration
|
private let configuration: Configuration
|
||||||
|
@ -143,6 +151,22 @@ public class SessionProxy {
|
||||||
|
|
||||||
private var authenticator: Authenticator?
|
private var authenticator: Authenticator?
|
||||||
|
|
||||||
|
// MARK: Caching
|
||||||
|
|
||||||
|
private let cachesURL: URL
|
||||||
|
|
||||||
|
private var caURL: URL {
|
||||||
|
return cachesURL.appendingPathComponent(Caches.ca)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var clientCertificateURL: URL {
|
||||||
|
return cachesURL.appendingPathComponent(Caches.clientCertificate)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var clientKeyURL: URL {
|
||||||
|
return cachesURL.appendingPathComponent(Caches.clientKey)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Init
|
// MARK: Init
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,9 +175,10 @@ public class SessionProxy {
|
||||||
- Parameter queue: The `DispatchQueue` where to run the session loop.
|
- Parameter queue: The `DispatchQueue` where to run the session loop.
|
||||||
- Parameter configuration: The `SessionProxy.Configuration` to use for this session.
|
- Parameter configuration: The `SessionProxy.Configuration` to use for this session.
|
||||||
*/
|
*/
|
||||||
public init(queue: DispatchQueue, configuration: Configuration) throws {
|
public init(queue: DispatchQueue, configuration: Configuration, cachesURL: URL) throws {
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.configuration = configuration
|
self.configuration = configuration
|
||||||
|
self.cachesURL = cachesURL
|
||||||
|
|
||||||
keys = [:]
|
keys = [:]
|
||||||
oldKeys = []
|
oldKeys = []
|
||||||
|
@ -172,10 +197,29 @@ public class SessionProxy {
|
||||||
} else {
|
} else {
|
||||||
controlChannel = ControlChannel()
|
controlChannel = ControlChannel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cache PEMs locally (mandatory for OpenSSL)
|
||||||
|
let fm = FileManager.default
|
||||||
|
try configuration.ca.pem.write(to: caURL, atomically: true, encoding: .ascii)
|
||||||
|
if let container = configuration.clientCertificate {
|
||||||
|
try container.pem.write(to: clientCertificateURL, atomically: true, encoding: .ascii)
|
||||||
|
} else {
|
||||||
|
try? fm.removeItem(at: clientCertificateURL)
|
||||||
|
}
|
||||||
|
if let container = configuration.clientKey {
|
||||||
|
try container.pem.write(to: clientKeyURL, atomically: true, encoding: .ascii)
|
||||||
|
} else {
|
||||||
|
try? fm.removeItem(at: clientKeyURL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
cleanup()
|
cleanup()
|
||||||
|
|
||||||
|
let fm = FileManager.default
|
||||||
|
for url in [caURL, clientCertificateURL, clientKeyURL] {
|
||||||
|
try? fm.removeItem(at: url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Public interface
|
// MARK: Public interface
|
||||||
|
@ -566,7 +610,7 @@ public class SessionProxy {
|
||||||
|
|
||||||
private func hardResetPayload() -> Data? {
|
private func hardResetPayload() -> Data? {
|
||||||
guard !configuration.usesPIAPatches else {
|
guard !configuration.usesPIAPatches else {
|
||||||
let caMD5 = TLSBox.md5(forCertificatePath: configuration.caPath)
|
let caMD5 = TLSBox.md5(forCertificatePath: caURL.path)
|
||||||
log.debug("CA MD5 is: \(caMD5)")
|
log.debug("CA MD5 is: \(caMD5)")
|
||||||
return try? PIAHardReset(
|
return try? PIAHardReset(
|
||||||
caMd5Digest: caMD5,
|
caMd5Digest: caMD5,
|
||||||
|
@ -722,9 +766,9 @@ public class SessionProxy {
|
||||||
log.debug("Start TLS handshake")
|
log.debug("Start TLS handshake")
|
||||||
|
|
||||||
negotiationKey.tlsOptional = TLSBox(
|
negotiationKey.tlsOptional = TLSBox(
|
||||||
caPath: configuration.caPath,
|
caPath: caURL.path,
|
||||||
clientCertificatePath: configuration.clientCertificatePath,
|
clientCertificatePath: (configuration.clientCertificate != nil) ? clientCertificateURL.path : nil,
|
||||||
clientKeyPath: configuration.clientKeyPath
|
clientKeyPath: (configuration.clientKey != nil) ? clientKeyURL.path : nil
|
||||||
)
|
)
|
||||||
do {
|
do {
|
||||||
try negotiationKey.tls.start()
|
try negotiationKey.tls.start()
|
||||||
|
|
Loading…
Reference in New Issue