Merge pull request #32 from keeshux/restore-pia-patches

Restore PIA patches
This commit is contained in:
Davide De Rosa 2018-10-18 16:34:40 +02:00 committed by GitHub
commit 69e5921163
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 204 additions and 9 deletions

View File

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project _will soon adhere_ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project _will soon adhere_ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Restore support for PIA patches. [#32](https://github.com/keeshux/tunnelkit/pull/32)
## 1.1.1 (2018-10-10) ## 1.1.1 (2018-10-10)
### Fixed ### Fixed

View File

@ -91,11 +91,12 @@ extension ViewController {
var builder = TunnelKitProvider.ConfigurationBuilder(ca: ca) var builder = TunnelKitProvider.ConfigurationBuilder(ca: ca)
let socketType: TunnelKitProvider.SocketType = switchTCP.isOn ? .tcp : .udp let socketType: TunnelKitProvider.SocketType = switchTCP.isOn ? .tcp : .udp
builder.endpointProtocols = [TunnelKitProvider.EndpointProtocol(socketType, port)] builder.endpointProtocols = [TunnelKitProvider.EndpointProtocol(socketType, port)]
builder.cipher = .aes128cbc builder.cipher = .aes256gcm
builder.digest = .sha1 builder.digest = .sha1
builder.mtu = 1350 builder.mtu = 1350
builder.compressionFraming = .compLZO builder.compressionFraming = .compLZO
builder.renegotiatesAfterSeconds = nil builder.renegotiatesAfterSeconds = nil
builder.usesPIAPatches = true
builder.shouldDebug = true builder.shouldDebug = true
builder.debugLogKey = "Log" builder.debugLogKey = "Log"

View File

@ -1,13 +1,13 @@
PODS: PODS:
- OpenSSL-Apple (1.1.0i-v2) - OpenSSL-Apple (1.1.0i-v2)
- SwiftyBeaver (1.6.1) - SwiftyBeaver (1.6.1)
- TunnelKit (1.1.0): - TunnelKit (1.1.2):
- TunnelKit/AppExtension (= 1.1.0) - TunnelKit/AppExtension (= 1.1.2)
- TunnelKit/Core (= 1.1.0) - TunnelKit/Core (= 1.1.2)
- TunnelKit/AppExtension (1.1.0): - TunnelKit/AppExtension (1.1.2):
- SwiftyBeaver - SwiftyBeaver
- TunnelKit/Core - TunnelKit/Core
- TunnelKit/Core (1.1.0): - TunnelKit/Core (1.1.2):
- OpenSSL-Apple (~> 1.1.0h) - OpenSSL-Apple (~> 1.1.0h)
- SwiftyBeaver - SwiftyBeaver
@ -26,7 +26,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c OpenSSL-Apple: a93b8f2eec8783ff40d9a9304de180ab68bb647c
SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a SwiftyBeaver: ccfcdf85a04d429f1633f668650b0ce8020bda3a
TunnelKit: 21af89c08aadfa81d25835a1faa46ddf12374772 TunnelKit: 392e78dd45cded30a6f814200b8334c33901f677
PODFILE CHECKSUM: f66dfaaa92a8d04ab2743f3caeab0ac9f9f25859 PODFILE CHECKSUM: f66dfaaa92a8d04ab2743f3caeab0ac9f9f25859

View File

@ -45,6 +45,9 @@
0E3E0F212108A8CC00B371C1 /* SessionProxy+PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */; }; 0E3E0F212108A8CC00B371C1 /* SessionProxy+PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */; };
0E3E0F222108A8CC00B371C1 /* SessionProxy+PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */; }; 0E3E0F222108A8CC00B371C1 /* SessionProxy+PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */; };
0E58F1302138AC2F00A49F27 /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58F12F2138AC2F00A49F27 /* DNSTests.swift */; }; 0E58F1302138AC2F00A49F27 /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58F12F2138AC2F00A49F27 /* DNSTests.swift */; };
0E749F622178911D00BB2701 /* pia-2048.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0E749F612178911C00BB2701 /* pia-2048.pem */; };
0E749F5F2178885500BB2701 /* SessionProxy+PIA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */; };
0E749F602178885500BB2701 /* SessionProxy+PIA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */; };
0E85A25A202CC5AF0059E9F9 /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */; }; 0E85A25A202CC5AF0059E9F9 /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */; };
0E9379C91F819A4300CE91B6 /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E17D7F91F730D9F009EE129 /* TunnelKit.framework */; }; 0E9379C91F819A4300CE91B6 /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E17D7F91F730D9F009EE129 /* TunnelKit.framework */; };
0EB2B45320F0BB44004233D7 /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */; }; 0EB2B45320F0BB44004233D7 /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */; };
@ -214,6 +217,8 @@
0E58F12F2138AC2F00A49F27 /* DNSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSTests.swift; sourceTree = "<group>"; }; 0E58F12F2138AC2F00A49F27 /* DNSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSTests.swift; sourceTree = "<group>"; };
0E6479DD212EAC96008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 0E6479DD212EAC96008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E6479E0212EACD6008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 0E6479E0212EACD6008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E749F612178911C00BB2701 /* pia-2048.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = "pia-2048.pem"; sourceTree = "<group>"; };
0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+PIA.swift"; sourceTree = "<group>"; };
0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppExtensionTests.swift; sourceTree = "<group>"; }; 0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppExtensionTests.swift; sourceTree = "<group>"; };
0E85A25B202CCA3D0059E9F9 /* TunnelKitHost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TunnelKitHost.entitlements; sourceTree = "<group>"; }; 0E85A25B202CCA3D0059E9F9 /* TunnelKitHost.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TunnelKitHost.entitlements; sourceTree = "<group>"; };
0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionTests.swift; sourceTree = "<group>"; }; 0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionTests.swift; sourceTree = "<group>"; };
@ -340,6 +345,7 @@
0EB2B45620F0BD16004233D7 /* RandomTests.swift */, 0EB2B45620F0BD16004233D7 /* RandomTests.swift */,
0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */, 0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */,
0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */, 0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */,
0E749F612178911C00BB2701 /* pia-2048.pem */,
); );
path = TunnelKitTests; path = TunnelKitTests;
sourceTree = "<group>"; sourceTree = "<group>";
@ -472,6 +478,7 @@
0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */, 0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */,
0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */, 0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */,
0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */, 0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */,
0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */,
0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */, 0E3E0F202108A8CC00B371C1 /* SessionProxy+PushReply.swift */,
0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */, 0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */,
0EFEB4442006D3C800F81029 /* TLSBox.h */, 0EFEB4442006D3C800F81029 /* TLSBox.h */,
@ -719,6 +726,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
0E749F622178911D00BB2701 /* pia-2048.pem in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -869,6 +877,7 @@
0EC1BBA520D71190007C4C7B /* DNSResolver.swift in Sources */, 0EC1BBA520D71190007C4C7B /* DNSResolver.swift in Sources */,
0EFEB4AB200760EC00F81029 /* MemoryDestination.swift in Sources */, 0EFEB4AB200760EC00F81029 /* MemoryDestination.swift in Sources */,
0EFEB4AE2007625E00F81029 /* Keychain.swift in Sources */, 0EFEB4AE2007625E00F81029 /* Keychain.swift in Sources */,
0E749F5F2178885500BB2701 /* SessionProxy+PIA.swift in Sources */,
0EBBF3002085196000E36B40 /* NWTCPConnectionState+Description.swift in Sources */, 0EBBF3002085196000E36B40 /* NWTCPConnectionState+Description.swift in Sources */,
0EFEB4622006D3C800F81029 /* SecureRandom.swift in Sources */, 0EFEB4622006D3C800F81029 /* SecureRandom.swift in Sources */,
0EFEB45D2006D3C800F81029 /* CryptoBox.m in Sources */, 0EFEB45D2006D3C800F81029 /* CryptoBox.m in Sources */,
@ -924,6 +933,7 @@
0EFEB4B12007627700F81029 /* MemoryDestination.swift in Sources */, 0EFEB4B12007627700F81029 /* MemoryDestination.swift in Sources */,
0EC1BBA620D712DE007C4C7B /* DNSResolver.swift in Sources */, 0EC1BBA620D712DE007C4C7B /* DNSResolver.swift in Sources */,
0EFEB4A02006D7F300F81029 /* ReplayProtector.m in Sources */, 0EFEB4A02006D7F300F81029 /* ReplayProtector.m in Sources */,
0E749F602178885500BB2701 /* SessionProxy+PIA.swift in Sources */,
0EFEB4992006D7F300F81029 /* SessionProxy.swift in Sources */, 0EFEB4992006D7F300F81029 /* SessionProxy.swift in Sources */,
0EBBF3012085196000E36B40 /* NWTCPConnectionState+Description.swift in Sources */, 0EBBF3012085196000E36B40 /* NWTCPConnectionState+Description.swift in Sources */,
0EFEB4962006D7F300F81029 /* ProtocolMacros.swift in Sources */, 0EFEB4962006D7F300F81029 /* ProtocolMacros.swift in Sources */,

View File

@ -146,6 +146,9 @@ extension TunnelKitProvider {
/// The number of seconds after which a renegotiation is started. Set to `nil` to disable renegotiation (default). /// The number of seconds after which a renegotiation is started. Set to `nil` to disable renegotiation (default).
public var renegotiatesAfterSeconds: Int? public var renegotiatesAfterSeconds: Int?
/// Server is patched for the PIA VPN provider.
public var usesPIAPatches: Bool?
// MARK: Debugging // MARK: Debugging
/// Enables debugging. If `true`, then `debugLogKey` is a mandatory field. /// Enables debugging. If `true`, then `debugLogKey` is a mandatory field.
@ -177,6 +180,7 @@ extension TunnelKitProvider {
compressionFraming = .disabled compressionFraming = .disabled
keepAliveSeconds = nil keepAliveSeconds = nil
renegotiatesAfterSeconds = nil renegotiatesAfterSeconds = nil
usesPIAPatches = false
shouldDebug = false shouldDebug = false
debugLogKey = nil debugLogKey = nil
debugLogFormat = nil debugLogFormat = nil
@ -232,6 +236,7 @@ extension TunnelKitProvider {
} }
keepAliveSeconds = providerConfiguration[S.keepAlive] as? Int keepAliveSeconds = providerConfiguration[S.keepAlive] as? Int
renegotiatesAfterSeconds = providerConfiguration[S.renegotiatesAfter] as? Int renegotiatesAfterSeconds = providerConfiguration[S.renegotiatesAfter] as? Int
usesPIAPatches = providerConfiguration[S.usesPIAPatches] as? Bool ?? false
shouldDebug = providerConfiguration[S.debug] as? Bool ?? false shouldDebug = providerConfiguration[S.debug] as? Bool ?? false
if shouldDebug { if shouldDebug {
@ -268,6 +273,7 @@ extension TunnelKitProvider {
compressionFraming: compressionFraming, compressionFraming: compressionFraming,
keepAliveSeconds: keepAliveSeconds, keepAliveSeconds: keepAliveSeconds,
renegotiatesAfterSeconds: renegotiatesAfterSeconds, renegotiatesAfterSeconds: renegotiatesAfterSeconds,
usesPIAPatches: usesPIAPatches,
shouldDebug: shouldDebug, shouldDebug: shouldDebug,
debugLogKey: shouldDebug ? debugLogKey : nil, debugLogKey: shouldDebug ? debugLogKey : nil,
debugLogFormat: shouldDebug ? debugLogFormat : nil debugLogFormat: shouldDebug ? debugLogFormat : nil
@ -304,6 +310,8 @@ extension TunnelKitProvider {
static let renegotiatesAfter = "RenegotiatesAfter" static let renegotiatesAfter = "RenegotiatesAfter"
static let usesPIAPatches = "UsesPIAPatches"
static let debug = "Debug" static let debug = "Debug"
static let debugLogKey = "DebugLogKey" static let debugLogKey = "DebugLogKey"
@ -347,6 +355,9 @@ extension TunnelKitProvider {
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.renegotiatesAfterSeconds` /// - Seealso: `TunnelKitProvider.ConfigurationBuilder.renegotiatesAfterSeconds`
public let renegotiatesAfterSeconds: Int? public let renegotiatesAfterSeconds: Int?
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.usesPIAPatches`
public let usesPIAPatches: Bool?
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.shouldDebug` /// - Seealso: `TunnelKitProvider.ConfigurationBuilder.shouldDebug`
public let shouldDebug: Bool public let shouldDebug: Bool
@ -428,6 +439,9 @@ extension TunnelKitProvider {
if let renegotiatesAfterSeconds = renegotiatesAfterSeconds { if let renegotiatesAfterSeconds = renegotiatesAfterSeconds {
dict[S.renegotiatesAfter] = renegotiatesAfterSeconds dict[S.renegotiatesAfter] = renegotiatesAfterSeconds
} }
if let usesPIAPatches = usesPIAPatches {
dict[S.usesPIAPatches] = usesPIAPatches
}
if let debugLogKey = debugLogKey { if let debugLogKey = debugLogKey {
dict[S.debugLogKey] = debugLogKey dict[S.debugLogKey] = debugLogKey
} }
@ -518,6 +532,7 @@ extension TunnelKitProvider.Configuration: Equatable {
builder.compressionFraming = compressionFraming builder.compressionFraming = compressionFraming
builder.keepAliveSeconds = keepAliveSeconds builder.keepAliveSeconds = keepAliveSeconds
builder.renegotiatesAfterSeconds = renegotiatesAfterSeconds builder.renegotiatesAfterSeconds = renegotiatesAfterSeconds
builder.usesPIAPatches = usesPIAPatches
builder.shouldDebug = shouldDebug builder.shouldDebug = shouldDebug
builder.debugLogKey = debugLogKey builder.debugLogKey = debugLogKey
builder.debugLogFormat = debugLogFormat builder.debugLogFormat = debugLogFormat

View File

@ -234,6 +234,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
if let renegotiatesAfterSeconds = cfg.renegotiatesAfterSeconds { if let renegotiatesAfterSeconds = cfg.renegotiatesAfterSeconds {
sessionConfiguration.renegotiatesAfter = TimeInterval(renegotiatesAfterSeconds) sessionConfiguration.renegotiatesAfter = TimeInterval(renegotiatesAfterSeconds)
} }
sessionConfiguration.usesPIAPatches = cfg.usesPIAPatches ?? false
let proxy: SessionProxy let proxy: SessionProxy
do { do {

View File

@ -162,6 +162,9 @@ extension SessionProxy {
/// The number of seconds after which a renegotiation should be initiated. If `nil`, the client will never initiate a renegotiation. /// The number of seconds after which a renegotiation should be initiated. If `nil`, the client will never initiate a renegotiation.
public var renegotiatesAfter: TimeInterval? public var renegotiatesAfter: TimeInterval?
/// Server is patched for the PIA VPN provider.
public var usesPIAPatches: Bool
/// :nodoc: /// :nodoc:
public init(caPath: String) { public init(caPath: String) {
credentials = nil credentials = nil
@ -173,6 +176,7 @@ extension SessionProxy {
compressionFraming = .disabled compressionFraming = .disabled
keepAliveInterval = nil keepAliveInterval = nil
renegotiatesAfter = nil renegotiatesAfter = nil
usesPIAPatches = false
} }
/** /**
@ -190,7 +194,8 @@ extension SessionProxy {
clientKeyPath: clientKeyPath, clientKeyPath: clientKeyPath,
compressionFraming: compressionFraming, compressionFraming: compressionFraming,
keepAliveInterval: keepAliveInterval, keepAliveInterval: keepAliveInterval,
renegotiatesAfter: renegotiatesAfter renegotiatesAfter: renegotiatesAfter,
usesPIAPatches: usesPIAPatches
) )
} }
} }
@ -224,5 +229,8 @@ extension SessionProxy {
/// - Seealso: `SessionProxy.ConfigurationBuilder.renegotiatesAfter` /// - Seealso: `SessionProxy.ConfigurationBuilder.renegotiatesAfter`
public let renegotiatesAfter: TimeInterval? public let renegotiatesAfter: TimeInterval?
/// - Seealso: `SessionProxy.ConfigurationBuilder.usesPIAPatches`
public let usesPIAPatches: Bool
} }
} }

View File

@ -0,0 +1,77 @@
//
// SessionProxy+PIA.swift
// TunnelKit
//
// Created by Davide De Rosa on 10/18/18.
// Copyright (c) 2018 Davide De Rosa. All rights reserved.
//
// https://github.com/keeshux
//
// This file is part of TunnelKit.
//
// TunnelKit is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// TunnelKit is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
//
// This file incorporates work covered by the following copyright and
// permission notice:
//
// Copyright (c) 2018-Present Private Internet Access
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//
import Foundation
extension SessionProxy {
struct PIAHardReset {
private static let obfuscationKeyLength = 3
private static let magic = "53eo0rk92gxic98p1asgl5auh59r1vp4lmry1e3chzi100qntd"
private static let encodedFormat = "\(magic)crypto\t%@|%@\tca\t%@"
private let caMd5Digest: String
private let cipherName: String
private let digestName: String
init(caMd5Digest: String, cipher: Cipher, digest: Digest) {
self.caMd5Digest = caMd5Digest
cipherName = cipher.rawValue.lowercased()
digestName = digest.rawValue.lowercased()
}
// Ruby: pia_settings
func encodedData() throws -> Data {
guard let plainData = String(format: PIAHardReset.encodedFormat, cipherName, digestName, caMd5Digest).data(using: .ascii) else {
fatalError("Unable to encode string to ASCII")
}
let keyBytes = try SecureRandom.data(length: PIAHardReset.obfuscationKeyLength)
var encodedData = Data(keyBytes)
for (i, b) in plainData.enumerated() {
let keyChar = keyBytes[i % keyBytes.count]
let xorredB = b ^ keyChar
encodedData.append(xorredB)
}
return encodedData
}
}
}

View File

@ -556,8 +556,22 @@ public class SessionProxy {
keys[negotiationKeyIdx] = newKey keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)") log.debug("Negotiation key index is \(negotiationKeyIdx)")
let payload = hardResetPayload() ?? Data()
negotiationKey.state = .hardReset negotiationKey.state = .hardReset
enqueueControlPackets(code: .hardResetClientV2, key: UInt8(negotiationKeyIdx), payload: Data()) enqueueControlPackets(code: .hardResetClientV2, key: UInt8(negotiationKeyIdx), payload: payload)
}
private func hardResetPayload() -> Data? {
guard !configuration.usesPIAPatches else {
let caMD5 = TLSBox.md5(forCertificatePath: configuration.caPath)
log.debug("CA MD5 is: \(caMD5)")
return try? PIAHardReset(
caMd5Digest: caMD5,
cipher: configuration.cipher,
digest: configuration.digest
).encodedData()
}
return nil
} }
// Ruby: soft_reset // Ruby: soft_reset

View File

@ -51,6 +51,8 @@ extern NSString *const TLSBoxPeerVerificationErrorNotification;
// //
@interface TLSBox : NSObject @interface TLSBox : NSObject
+ (NSString *)md5ForCertificatePath:(NSString *)path;
- (instancetype)initWithCAPath:(NSString *)caPath - (instancetype)initWithCAPath:(NSString *)caPath
clientCertificatePath:(nullable NSString *)clientCertificatePath clientCertificatePath:(nullable NSString *)clientCertificatePath
clientKeyPath:(nullable NSString *)clientKeyPath; clientKeyPath:(nullable NSString *)clientKeyPath;

View File

@ -75,6 +75,25 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
@implementation TLSBox @implementation TLSBox
+ (NSString *)md5ForCertificatePath:(NSString *)path
{
const EVP_MD *alg = EVP_get_digestbyname("MD5");
uint8_t md[16];
unsigned int len;
FILE *pem = fopen([path cStringUsingEncoding:NSASCIIStringEncoding], "r");
X509 *cert = PEM_read_X509(pem, NULL, NULL, NULL);
X509_digest(cert, alg, md, &len);
X509_free(cert);
NSCAssert2(len == sizeof(md), @"Unexpected MD5 size (%d != %lu)", len, sizeof(md));
NSMutableString *hex = [[NSMutableString alloc] initWithCapacity:2 * sizeof(md)];
for (int i = 0; i < sizeof(md); ++i) {
[hex appendFormat:@"%02x", md[i]];
}
return hex;
}
- (instancetype)init - (instancetype)init
{ {
[NSException raise:NSInvalidArgumentException format:@"Use initWithCAPath:clientCertificatePath:clientKeyPath:"]; [NSException raise:NSInvalidArgumentException format:@"Use initWithCAPath:clientCertificatePath:clientKeyPath:"];

View File

@ -86,6 +86,14 @@ class EncryptionTests: XCTestCase {
let decrypted = try! server.decrypter().decryptData(encrypted, extra: extra) let decrypted = try! server.decrypter().decryptData(encrypted, extra: extra)
XCTAssertEqual(plain, decrypted) XCTAssertEqual(plain, decrypted)
} }
func testCertificateMD5() {
let path = Bundle(for: EncryptionTests.self).path(forResource: "pia-2048", ofType: "pem")!
let md5 = TLSBox.md5(forCertificatePath: path)
let exp = "e2fccccaba712ccc68449b1c56427ac1"
print(md5)
XCTAssertEqual(md5, exp)
}
private func clientServer(_ c: String?, _ d: String?) -> (CryptoBox, CryptoBox) { private func clientServer(_ c: String?, _ d: String?) -> (CryptoBox, CryptoBox) {
let client = CryptoBox(cipherAlgorithm: c, digestAlgorithm: d) let client = CryptoBox(cipherAlgorithm: c, digestAlgorithm: d)

View File

@ -0,0 +1,34 @@
-----BEGIN CERTIFICATE-----
MIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV
BAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu
dGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx
IDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB
FiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1
MThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex
EzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg
QWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE
AxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50
ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy
bmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD
L1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX
lH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp
cdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/
8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB
/5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC
OfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL
y8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO
sqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM
b3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G
A1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg
SW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz
czEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j
b22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn
a5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU
ryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3
7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC
GohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz
1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt
YDQ8z9v+DMO6iwyIDRiU
-----END CERTIFICATE-----