Work around cipher/digest/framing issues
- Make them optional - Set default values inside SessionProxy Fallback is not needed anywhere else.
This commit is contained in:
parent
0d86bd20b6
commit
55534df6fa
|
@ -431,16 +431,22 @@ extension TunnelKitProvider {
|
||||||
var dict: [String: Any] = [
|
var dict: [String: Any] = [
|
||||||
S.appGroup: appGroup,
|
S.appGroup: appGroup,
|
||||||
S.prefersResolvedAddresses: prefersResolvedAddresses,
|
S.prefersResolvedAddresses: prefersResolvedAddresses,
|
||||||
S.cipherAlgorithm: sessionConfiguration.cipher.rawValue,
|
|
||||||
S.digestAlgorithm: sessionConfiguration.digest.rawValue,
|
|
||||||
S.compressionFraming: sessionConfiguration.compressionFraming.rawValue,
|
|
||||||
S.ca: ca.pem,
|
S.ca: ca.pem,
|
||||||
S.endpointProtocols: endpointProtocols.map { $0.rawValue },
|
S.endpointProtocols: endpointProtocols.map { $0.rawValue },
|
||||||
S.mtu: mtu,
|
S.mtu: mtu,
|
||||||
S.debug: shouldDebug
|
S.debug: shouldDebug
|
||||||
]
|
]
|
||||||
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm?.rawValue {
|
if let cipher = sessionConfiguration.cipher {
|
||||||
dict[S.compressionAlgorithm] = compressionAlgorithm
|
dict[S.cipherAlgorithm] = cipher.rawValue
|
||||||
|
}
|
||||||
|
if let digest = sessionConfiguration.digest {
|
||||||
|
dict[S.digestAlgorithm] = digest.rawValue
|
||||||
|
}
|
||||||
|
if let compressionFraming = sessionConfiguration.compressionFraming {
|
||||||
|
dict[S.compressionFraming] = compressionFraming.rawValue
|
||||||
|
}
|
||||||
|
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm {
|
||||||
|
dict[S.compressionAlgorithm] = compressionAlgorithm.rawValue
|
||||||
}
|
}
|
||||||
if let clientCertificate = sessionConfiguration.clientCertificate {
|
if let clientCertificate = sessionConfiguration.clientCertificate {
|
||||||
dict[S.clientCertificate] = clientCertificate.pem
|
dict[S.clientCertificate] = clientCertificate.pem
|
||||||
|
@ -525,9 +531,9 @@ extension TunnelKitProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("\tProtocols: \(endpointProtocols)")
|
log.info("\tProtocols: \(endpointProtocols)")
|
||||||
log.info("\tCipher: \(sessionConfiguration.cipher)")
|
log.info("\tCipher: \(sessionConfiguration.fallbackCipher)")
|
||||||
log.info("\tDigest: \(sessionConfiguration.digest)")
|
log.info("\tDigest: \(sessionConfiguration.fallbackDigest)")
|
||||||
log.info("\tCompression framing: \(sessionConfiguration.compressionFraming)")
|
log.info("\tCompression framing: \(sessionConfiguration.fallbackCompressionFraming)")
|
||||||
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm, compressionAlgorithm != .disabled {
|
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm, compressionAlgorithm != .disabled {
|
||||||
log.info("\tCompression algorithm: \(compressionAlgorithm)")
|
log.info("\tCompression algorithm: \(compressionAlgorithm)")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -483,10 +483,10 @@ public class ConfigurationParser {
|
||||||
|
|
||||||
// MARK: General
|
// MARK: General
|
||||||
|
|
||||||
sessionBuilder.cipher = optCipher ?? .aes128cbc // FIXME: non-optional breaks PUSH_REPLY
|
sessionBuilder.cipher = optCipher
|
||||||
sessionBuilder.digest = optDigest ?? .sha1 // FIXME: non-optional breaks PUSH_REPLY
|
sessionBuilder.digest = optDigest
|
||||||
sessionBuilder.compressionFraming = optCompressionFraming ?? .disabled // FIXME: non-optional breaks PUSH_REPLY
|
sessionBuilder.compressionFraming = optCompressionFraming
|
||||||
sessionBuilder.compressionAlgorithm = optCompressionAlgorithm ?? .disabled
|
sessionBuilder.compressionAlgorithm = optCompressionAlgorithm
|
||||||
sessionBuilder.ca = optCA
|
sessionBuilder.ca = optCA
|
||||||
sessionBuilder.clientCertificate = optClientCertificate
|
sessionBuilder.clientCertificate = optClientCertificate
|
||||||
|
|
||||||
|
|
|
@ -132,19 +132,28 @@ extension SessionProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
private struct Fallback {
|
||||||
|
static let cipher: Cipher = .aes128cbc
|
||||||
|
|
||||||
|
static let digest: Digest = .sha1
|
||||||
|
|
||||||
|
static let compressionFraming: CompressionFraming = .disabled
|
||||||
|
}
|
||||||
|
|
||||||
/// The way to create a `SessionProxy.Configuration` object for a `SessionProxy`.
|
/// The way to create a `SessionProxy.Configuration` object for a `SessionProxy`.
|
||||||
public struct ConfigurationBuilder {
|
public struct ConfigurationBuilder {
|
||||||
|
|
||||||
// MARK: General
|
// MARK: General
|
||||||
|
|
||||||
/// The cipher algorithm for data encryption.
|
/// The cipher algorithm for data encryption.
|
||||||
public var cipher: SessionProxy.Cipher
|
public var cipher: SessionProxy.Cipher?
|
||||||
|
|
||||||
/// The digest algorithm for HMAC.
|
/// The digest algorithm for HMAC.
|
||||||
public var digest: SessionProxy.Digest
|
public var digest: SessionProxy.Digest?
|
||||||
|
|
||||||
/// Compression framing, disabled by default.
|
/// Compression framing, disabled by default.
|
||||||
public var compressionFraming: SessionProxy.CompressionFraming
|
public var compressionFraming: SessionProxy.CompressionFraming?
|
||||||
|
|
||||||
/// Compression algorithm, disabled by default.
|
/// Compression algorithm, disabled by default.
|
||||||
public var compressionAlgorithm: SessionProxy.CompressionAlgorithm?
|
public var compressionAlgorithm: SessionProxy.CompressionAlgorithm?
|
||||||
|
@ -210,31 +219,6 @@ extension SessionProxy {
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// :nodoc:
|
|
||||||
public init() {
|
|
||||||
cipher = .aes128cbc
|
|
||||||
digest = .sha1
|
|
||||||
compressionFraming = .disabled
|
|
||||||
compressionAlgorithm = nil
|
|
||||||
ca = nil
|
|
||||||
clientCertificate = nil
|
|
||||||
clientKey = nil
|
|
||||||
tlsWrap = nil
|
|
||||||
keepAliveInterval = nil
|
|
||||||
renegotiatesAfter = nil
|
|
||||||
hostname = nil
|
|
||||||
endpointProtocols = nil
|
|
||||||
checksEKU = false
|
|
||||||
randomizeEndpoint = false
|
|
||||||
usesPIAPatches = false
|
|
||||||
authToken = nil
|
|
||||||
peerId = nil
|
|
||||||
ipv4 = nil
|
|
||||||
ipv6 = nil
|
|
||||||
dnsServers = nil
|
|
||||||
searchDomain = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Builds a `SessionProxy.Configuration` object.
|
Builds a `SessionProxy.Configuration` object.
|
||||||
|
|
||||||
|
@ -265,19 +249,36 @@ extension SessionProxy {
|
||||||
searchDomain: searchDomain
|
searchDomain: searchDomain
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Shortcuts
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackCipher: Cipher {
|
||||||
|
return cipher ?? Fallback.cipher
|
||||||
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackDigest: Digest {
|
||||||
|
return digest ?? Fallback.digest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackCompressionFraming: CompressionFraming {
|
||||||
|
return compressionFraming ?? Fallback.compressionFraming
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The immutable configuration for `SessionProxy`.
|
/// The immutable configuration for `SessionProxy`.
|
||||||
public struct Configuration: Codable {
|
public struct Configuration: Codable {
|
||||||
|
|
||||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.cipher`
|
/// - Seealso: `SessionProxy.ConfigurationBuilder.cipher`
|
||||||
public let cipher: Cipher
|
public let cipher: Cipher?
|
||||||
|
|
||||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.digest`
|
/// - Seealso: `SessionProxy.ConfigurationBuilder.digest`
|
||||||
public let digest: Digest
|
public let digest: Digest?
|
||||||
|
|
||||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
|
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
|
||||||
public let compressionFraming: CompressionFraming
|
public let compressionFraming: CompressionFraming?
|
||||||
|
|
||||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
|
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
|
||||||
public let compressionAlgorithm: CompressionAlgorithm?
|
public let compressionAlgorithm: CompressionAlgorithm?
|
||||||
|
@ -362,6 +363,23 @@ extension SessionProxy {
|
||||||
builder.searchDomain = searchDomain
|
builder.searchDomain = searchDomain
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Shortcuts
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackCipher: Cipher {
|
||||||
|
return cipher ?? Fallback.cipher
|
||||||
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackDigest: Digest {
|
||||||
|
return digest ?? Fallback.digest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// :nodoc:
|
||||||
|
public var fallbackCompressionFraming: CompressionFraming {
|
||||||
|
return compressionFraming ?? Fallback.compressionFraming
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ public class SessionProxy {
|
||||||
if let tlsWrap = configuration.tlsWrap {
|
if let tlsWrap = configuration.tlsWrap {
|
||||||
switch tlsWrap.strategy {
|
switch tlsWrap.strategy {
|
||||||
case .auth:
|
case .auth:
|
||||||
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.digest)
|
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest)
|
||||||
|
|
||||||
case .crypt:
|
case .crypt:
|
||||||
controlChannel = try ControlChannel(withCryptKey: tlsWrap.key)
|
controlChannel = try ControlChannel(withCryptKey: tlsWrap.key)
|
||||||
|
@ -634,8 +634,8 @@ public class SessionProxy {
|
||||||
log.debug("CA MD5 is: \(caMD5)")
|
log.debug("CA MD5 is: \(caMD5)")
|
||||||
return try? PIAHardReset(
|
return try? PIAHardReset(
|
||||||
caMd5Digest: caMD5,
|
caMd5Digest: caMD5,
|
||||||
cipher: configuration.cipher,
|
cipher: configuration.fallbackCipher,
|
||||||
digest: configuration.digest
|
digest: configuration.fallbackDigest
|
||||||
).encodedData()
|
).encodedData()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -923,10 +923,7 @@ public class SessionProxy {
|
||||||
reply = optionalReply
|
reply = optionalReply
|
||||||
log.debug("Received PUSH_REPLY: \"\(reply.maskedDescription)\"")
|
log.debug("Received PUSH_REPLY: \"\(reply.maskedDescription)\"")
|
||||||
|
|
||||||
// FIXME: non-optional breaks PUSH_REPLY
|
if let framing = reply.options.compressionFraming, let compression = reply.options.compressionAlgorithm {
|
||||||
// if let framing = reply.options.compressionFraming, let compression = reply.options.compressionAlgorithm {
|
|
||||||
let framing = reply.options.compressionFraming
|
|
||||||
if framing != .disabled, let compression = reply.options.compressionAlgorithm {
|
|
||||||
switch compression {
|
switch compression {
|
||||||
case .disabled:
|
case .disabled:
|
||||||
break
|
break
|
||||||
|
@ -1043,20 +1040,18 @@ public class SessionProxy {
|
||||||
log.debug("Set up encryption")
|
log.debug("Set up encryption")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pushedCipher = pushReply.options.cipher
|
||||||
|
if let negCipher = pushedCipher {
|
||||||
|
log.info("\tNegotiated cipher: \(negCipher.rawValue)")
|
||||||
|
}
|
||||||
let pushedFraming = pushReply.options.compressionFraming
|
let pushedFraming = pushReply.options.compressionFraming
|
||||||
// FIXME: non-optional breaks PUSH_REPLY
|
if let negFraming = pushedFraming {
|
||||||
// if let negFraming = pushedFraming {
|
log.info("\tNegotiated compression framing: \(negFraming)")
|
||||||
// log.info("\tNegotiated compression framing: \(negFraming)")
|
}
|
||||||
// }
|
|
||||||
let pushedCompression = pushReply.options.compressionAlgorithm
|
let pushedCompression = pushReply.options.compressionAlgorithm
|
||||||
if let negCompression = pushedCompression {
|
if let negCompression = pushedCompression {
|
||||||
log.info("\tNegotiated compression algorithm: \(negCompression)")
|
log.info("\tNegotiated compression algorithm: \(negCompression)")
|
||||||
}
|
}
|
||||||
let pushedCipher = pushReply.options.cipher
|
|
||||||
// FIXME: non-optional breaks PUSH_REPLY
|
|
||||||
// if let negCipher = pushedCipher {
|
|
||||||
// log.info("\tNegotiated cipher: \(negCipher.rawValue)")
|
|
||||||
// }
|
|
||||||
if let negPing = pushReply.options.keepAliveInterval {
|
if let negPing = pushReply.options.keepAliveInterval {
|
||||||
log.info("\tNegotiated keep-alive: \(negPing) seconds")
|
log.info("\tNegotiated keep-alive: \(negPing) seconds")
|
||||||
}
|
}
|
||||||
|
@ -1064,9 +1059,8 @@ public class SessionProxy {
|
||||||
let bridge: EncryptionBridge
|
let bridge: EncryptionBridge
|
||||||
do {
|
do {
|
||||||
bridge = try EncryptionBridge(
|
bridge = try EncryptionBridge(
|
||||||
// FIXME: non-optional breaks PUSH_REPLY
|
pushedCipher ?? configuration.fallbackCipher,
|
||||||
pushedCipher ?? configuration.cipher,
|
configuration.fallbackDigest,
|
||||||
configuration.digest,
|
|
||||||
auth,
|
auth,
|
||||||
sessionId,
|
sessionId,
|
||||||
remoteSessionId
|
remoteSessionId
|
||||||
|
@ -1080,8 +1074,7 @@ public class SessionProxy {
|
||||||
encrypter: bridge.encrypter(),
|
encrypter: bridge.encrypter(),
|
||||||
decrypter: bridge.decrypter(),
|
decrypter: bridge.decrypter(),
|
||||||
peerId: pushReply.options.peerId ?? PacketPeerIdDisabled,
|
peerId: pushReply.options.peerId ?? PacketPeerIdDisabled,
|
||||||
// FIXME: non-optional breaks PUSH_REPLY
|
compressionFraming: (pushedFraming ?? configuration.fallbackCompressionFraming).native,
|
||||||
compressionFraming: (pushedFraming ?? configuration.compressionFraming).native,
|
|
||||||
compressionAlgorithm: (pushedCompression ?? configuration.compressionAlgorithm ?? .disabled).native,
|
compressionAlgorithm: (pushedCompression ?? configuration.compressionAlgorithm ?? .disabled).native,
|
||||||
maxPackets: link?.packetBufferSize ?? 200,
|
maxPackets: link?.packetBufferSize ?? 200,
|
||||||
usesReplayProtection: CoreConfiguration.usesReplayProtection
|
usesReplayProtection: CoreConfiguration.usesReplayProtection
|
||||||
|
|
|
@ -84,8 +84,8 @@ class AppExtensionTests: XCTestCase {
|
||||||
|
|
||||||
let K = TunnelKitProvider.Configuration.Keys.self
|
let K = TunnelKitProvider.Configuration.Keys.self
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.appGroup] as? String, appGroup)
|
XCTAssertEqual(proto?.providerConfiguration?[K.appGroup] as? String, appGroup)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.cipherAlgorithm] as? String, cfg.sessionConfiguration.cipher.rawValue)
|
XCTAssertEqual(proto?.providerConfiguration?[K.cipherAlgorithm] as? String, cfg.sessionConfiguration.cipher?.rawValue)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.digestAlgorithm] as? String, cfg.sessionConfiguration.digest.rawValue)
|
XCTAssertEqual(proto?.providerConfiguration?[K.digestAlgorithm] as? String, cfg.sessionConfiguration.digest?.rawValue)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.sessionConfiguration.ca?.pem)
|
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.sessionConfiguration.ca?.pem)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.mtu] as? Int, cfg.mtu)
|
XCTAssertEqual(proto?.providerConfiguration?[K.mtu] as? Int, cfg.mtu)
|
||||||
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? TimeInterval, cfg.sessionConfiguration.renegotiatesAfter)
|
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? TimeInterval, cfg.sessionConfiguration.renegotiatesAfter)
|
||||||
|
|
|
@ -28,8 +28,8 @@ import XCTest
|
||||||
|
|
||||||
private extension SessionReply {
|
private extension SessionReply {
|
||||||
func debug() {
|
func debug() {
|
||||||
print("Compression framing: \(options.compressionFraming.description ?? "none")")
|
print("Compression framing: \(options.compressionFraming?.description ?? "disabled")")
|
||||||
print("Compression algorithm: \(options.compressionAlgorithm?.description ?? "none")")
|
print("Compression algorithm: \(options.compressionAlgorithm?.description ?? "disabled")")
|
||||||
print("IPv4: \(options.ipv4?.description ?? "none")")
|
print("IPv4: \(options.ipv4?.description ?? "none")")
|
||||||
print("IPv6: \(options.ipv6?.description ?? "none")")
|
print("IPv6: \(options.ipv6?.description ?? "none")")
|
||||||
print("DNS: \(options.dnsServers?.description ?? "none")")
|
print("DNS: \(options.dnsServers?.description ?? "none")")
|
||||||
|
|
Loading…
Reference in New Issue