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:
Davide De Rosa 2019-04-04 13:01:32 +02:00
parent 0d86bd20b6
commit 55534df6fa
6 changed files with 85 additions and 68 deletions

View File

@ -431,16 +431,22 @@ extension TunnelKitProvider {
var dict: [String: Any] = [
S.appGroup: appGroup,
S.prefersResolvedAddresses: prefersResolvedAddresses,
S.cipherAlgorithm: sessionConfiguration.cipher.rawValue,
S.digestAlgorithm: sessionConfiguration.digest.rawValue,
S.compressionFraming: sessionConfiguration.compressionFraming.rawValue,
S.ca: ca.pem,
S.endpointProtocols: endpointProtocols.map { $0.rawValue },
S.mtu: mtu,
S.debug: shouldDebug
]
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm?.rawValue {
dict[S.compressionAlgorithm] = compressionAlgorithm
if let cipher = sessionConfiguration.cipher {
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 {
dict[S.clientCertificate] = clientCertificate.pem
@ -525,9 +531,9 @@ extension TunnelKitProvider {
}
log.info("\tProtocols: \(endpointProtocols)")
log.info("\tCipher: \(sessionConfiguration.cipher)")
log.info("\tDigest: \(sessionConfiguration.digest)")
log.info("\tCompression framing: \(sessionConfiguration.compressionFraming)")
log.info("\tCipher: \(sessionConfiguration.fallbackCipher)")
log.info("\tDigest: \(sessionConfiguration.fallbackDigest)")
log.info("\tCompression framing: \(sessionConfiguration.fallbackCompressionFraming)")
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm, compressionAlgorithm != .disabled {
log.info("\tCompression algorithm: \(compressionAlgorithm)")
} else {

View File

@ -483,10 +483,10 @@ public class ConfigurationParser {
// MARK: General
sessionBuilder.cipher = optCipher ?? .aes128cbc // FIXME: non-optional breaks PUSH_REPLY
sessionBuilder.digest = optDigest ?? .sha1 // FIXME: non-optional breaks PUSH_REPLY
sessionBuilder.compressionFraming = optCompressionFraming ?? .disabled // FIXME: non-optional breaks PUSH_REPLY
sessionBuilder.compressionAlgorithm = optCompressionAlgorithm ?? .disabled
sessionBuilder.cipher = optCipher
sessionBuilder.digest = optDigest
sessionBuilder.compressionFraming = optCompressionFraming
sessionBuilder.compressionAlgorithm = optCompressionAlgorithm
sessionBuilder.ca = optCA
sessionBuilder.clientCertificate = optClientCertificate

View File

@ -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`.
public struct ConfigurationBuilder {
// MARK: General
/// The cipher algorithm for data encryption.
public var cipher: SessionProxy.Cipher
public var cipher: SessionProxy.Cipher?
/// The digest algorithm for HMAC.
public var digest: SessionProxy.Digest
public var digest: SessionProxy.Digest?
/// Compression framing, disabled by default.
public var compressionFraming: SessionProxy.CompressionFraming
public var compressionFraming: SessionProxy.CompressionFraming?
/// Compression algorithm, disabled by default.
public var compressionAlgorithm: SessionProxy.CompressionAlgorithm?
@ -210,31 +219,6 @@ extension SessionProxy {
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.
@ -265,19 +249,36 @@ extension SessionProxy {
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`.
public struct Configuration: Codable {
/// - Seealso: `SessionProxy.ConfigurationBuilder.cipher`
public let cipher: Cipher
public let cipher: Cipher?
/// - Seealso: `SessionProxy.ConfigurationBuilder.digest`
public let digest: Digest
public let digest: Digest?
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
public let compressionFraming: CompressionFraming
public let compressionFraming: CompressionFraming?
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
public let compressionAlgorithm: CompressionAlgorithm?
@ -362,6 +363,23 @@ extension SessionProxy {
builder.searchDomain = searchDomain
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
}
}
}

View File

@ -196,7 +196,7 @@ public class SessionProxy {
if let tlsWrap = configuration.tlsWrap {
switch tlsWrap.strategy {
case .auth:
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.digest)
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest)
case .crypt:
controlChannel = try ControlChannel(withCryptKey: tlsWrap.key)
@ -634,8 +634,8 @@ public class SessionProxy {
log.debug("CA MD5 is: \(caMD5)")
return try? PIAHardReset(
caMd5Digest: caMD5,
cipher: configuration.cipher,
digest: configuration.digest
cipher: configuration.fallbackCipher,
digest: configuration.fallbackDigest
).encodedData()
}
return nil
@ -923,10 +923,7 @@ public class SessionProxy {
reply = optionalReply
log.debug("Received PUSH_REPLY: \"\(reply.maskedDescription)\"")
// FIXME: non-optional breaks PUSH_REPLY
// if let framing = reply.options.compressionFraming, let compression = reply.options.compressionAlgorithm {
let framing = reply.options.compressionFraming
if framing != .disabled, let compression = reply.options.compressionAlgorithm {
if let framing = reply.options.compressionFraming, let compression = reply.options.compressionAlgorithm {
switch compression {
case .disabled:
break
@ -1043,20 +1040,18 @@ public class SessionProxy {
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
// FIXME: non-optional breaks PUSH_REPLY
// if let negFraming = pushedFraming {
// log.info("\tNegotiated compression framing: \(negFraming)")
// }
if let negFraming = pushedFraming {
log.info("\tNegotiated compression framing: \(negFraming)")
}
let pushedCompression = pushReply.options.compressionAlgorithm
if let negCompression = pushedCompression {
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 {
log.info("\tNegotiated keep-alive: \(negPing) seconds")
}
@ -1064,9 +1059,8 @@ public class SessionProxy {
let bridge: EncryptionBridge
do {
bridge = try EncryptionBridge(
// FIXME: non-optional breaks PUSH_REPLY
pushedCipher ?? configuration.cipher,
configuration.digest,
pushedCipher ?? configuration.fallbackCipher,
configuration.fallbackDigest,
auth,
sessionId,
remoteSessionId
@ -1080,8 +1074,7 @@ public class SessionProxy {
encrypter: bridge.encrypter(),
decrypter: bridge.decrypter(),
peerId: pushReply.options.peerId ?? PacketPeerIdDisabled,
// FIXME: non-optional breaks PUSH_REPLY
compressionFraming: (pushedFraming ?? configuration.compressionFraming).native,
compressionFraming: (pushedFraming ?? configuration.fallbackCompressionFraming).native,
compressionAlgorithm: (pushedCompression ?? configuration.compressionAlgorithm ?? .disabled).native,
maxPackets: link?.packetBufferSize ?? 200,
usesReplayProtection: CoreConfiguration.usesReplayProtection

View File

@ -84,8 +84,8 @@ class AppExtensionTests: XCTestCase {
let K = TunnelKitProvider.Configuration.Keys.self
XCTAssertEqual(proto?.providerConfiguration?[K.appGroup] as? String, appGroup)
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.cipherAlgorithm] as? String, cfg.sessionConfiguration.cipher?.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.mtu] as? Int, cfg.mtu)
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? TimeInterval, cfg.sessionConfiguration.renegotiatesAfter)

View File

@ -28,8 +28,8 @@ import XCTest
private extension SessionReply {
func debug() {
print("Compression framing: \(options.compressionFraming.description ?? "none")")
print("Compression algorithm: \(options.compressionAlgorithm?.description ?? "none")")
print("Compression framing: \(options.compressionFraming?.description ?? "disabled")")
print("Compression algorithm: \(options.compressionAlgorithm?.description ?? "disabled")")
print("IPv4: \(options.ipv4?.description ?? "none")")
print("IPv6: \(options.ipv6?.description ?? "none")")
print("DNS: \(options.dnsServers?.description ?? "none")")