Merge branch 'wrap-protocol-specifics'

This commit is contained in:
Davide De Rosa 2019-05-23 20:07:42 +02:00
commit 011a407edd
33 changed files with 1845 additions and 1779 deletions

View File

@ -22,17 +22,15 @@ custom_categories:
- IPv6Settings
- LinkInterface
- Proxy
- TunnelInterface
- Session
- SocketType
- TunnelInterface
- name: OpenVPN
children:
- ConfigurationParser
- CryptoContainer
- SessionError
- SessionProxy
- SessionProxyDelegate
- SessionReply
- StaticKey
- OpenVPN
- OpenVPNError
- OpenVPNSession
- OpenVPNSessionDelegate
- name: AppExtension
children:
- TunnelKitProvider

View File

@ -18,8 +18,7 @@ Pod::Spec.new do |s|
p.source_files = "TunnelKit/Sources/Core/**/*.{h,m,swift}"
p.private_header_files = "TunnelKit/Sources/Core/**/*.h"
p.preserve_paths = "TunnelKit/Sources/Core/*.modulemap"
p.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-framework openssl",
"SWIFT_INCLUDE_PATHS" => "${PODS_TARGET_SRCROOT}/TunnelKit/Sources/Core",
p.pod_target_xcconfig = { "SWIFT_INCLUDE_PATHS" => "${PODS_TARGET_SRCROOT}/TunnelKit/Sources/Core",
"APPLICATION_EXTENSION_API_ONLY" => "YES" }
p.dependency "SwiftyBeaver"
p.dependency "OpenSSL-Apple", "~> 1.1.0j.2"
@ -30,7 +29,8 @@ Pod::Spec.new do |s|
p.source_files = "TunnelKit/Sources/OpenVPN/**/*.{h,m,swift}"
p.private_header_files = "TunnelKit/Sources/OpenVPN/**/*.h"
p.preserve_paths = "TunnelKit/Sources/OpenVPN/*.modulemap"
p.pod_target_xcconfig = { "SWIFT_INCLUDE_PATHS" => "${PODS_TARGET_SRCROOT}/TunnelKit/Sources/OpenVPN",
p.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-framework openssl",
"SWIFT_INCLUDE_PATHS" => "${PODS_TARGET_SRCROOT}/TunnelKit/Sources/OpenVPN",
"APPLICATION_EXTENSION_API_ONLY" => "YES" }
p.dependency "TunnelKit/Core"

View File

@ -11,15 +11,12 @@
0E011F7B2196D93600BA59EE /* SocketType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F792196D93600BA59EE /* SocketType.swift */; };
0E011F7D2196D97200BA59EE /* EndpointProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F7C2196D97200BA59EE /* EndpointProtocol.swift */; };
0E011F7E2196D97200BA59EE /* EndpointProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F7C2196D97200BA59EE /* EndpointProtocol.swift */; };
0E011F812196E23700BA59EE /* ConfigurationParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F7F2196E20300BA59EE /* ConfigurationParserTests.swift */; };
0E011F822196E23800BA59EE /* ConfigurationParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F7F2196E20300BA59EE /* ConfigurationParserTests.swift */; };
0E011F852196E25900BA59EE /* pia-hungary.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0E011F832196E25400BA59EE /* pia-hungary.ovpn */; };
0E011F862196E25A00BA59EE /* pia-hungary.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0E011F832196E25400BA59EE /* pia-hungary.ovpn */; };
0E011F882196E2AB00BA59EE /* ConfigurationParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F872196E2AB00BA59EE /* ConfigurationParser.swift */; };
0E011F892196E2AB00BA59EE /* ConfigurationParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E011F872196E2AB00BA59EE /* ConfigurationParser.swift */; };
0E041D092152E6FE0025FE3C /* SessionProxy+TLSWrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D082152E6FE0025FE3C /* SessionProxy+TLSWrap.swift */; };
0E041D0A2152E6FE0025FE3C /* SessionProxy+TLSWrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D082152E6FE0025FE3C /* SessionProxy+TLSWrap.swift */; };
0E041D0C2152E80A0025FE3C /* StaticKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D0B2152E80A0025FE3C /* StaticKeyTests.swift */; };
0E041D092152E6FE0025FE3C /* TLSWrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D082152E6FE0025FE3C /* TLSWrap.swift */; };
0E041D0A2152E6FE0025FE3C /* TLSWrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D082152E6FE0025FE3C /* TLSWrap.swift */; };
0E07595F20EF6D1400F38FD8 /* CryptoCBC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */; };
0E07596020EF6D1400F38FD8 /* CryptoCBC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */; };
0E07596320EF733F00F38FD8 /* CryptoMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07596120EF733F00F38FD8 /* CryptoMacros.h */; };
@ -32,16 +29,14 @@
0E07597F20F0060E00F38FD8 /* CryptoAEAD.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */; };
0E07598020F0060E00F38FD8 /* CryptoAEAD.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */; };
0E07598120F0060E00F38FD8 /* CryptoAEAD.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */; };
0E0B203C227886AD007A3CB9 /* RoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0B203B227886AD007A3CB9 /* RoutingTests.swift */; };
0E0B203D227886AD007A3CB9 /* RoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0B203B227886AD007A3CB9 /* RoutingTests.swift */; };
0E0B20402278A85C007A3CB9 /* RoutingTableEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E0B203E2278A85B007A3CB9 /* RoutingTableEntry.h */; };
0E0B20412278A85C007A3CB9 /* RoutingTableEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E0B203E2278A85B007A3CB9 /* RoutingTableEntry.h */; };
0E0B20422278A85C007A3CB9 /* RoutingTableEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E0B203F2278A85B007A3CB9 /* RoutingTableEntry.m */; };
0E0B20432278A85C007A3CB9 /* RoutingTableEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E0B203F2278A85B007A3CB9 /* RoutingTableEntry.m */; };
0E0C2125212ED29D008AB282 /* SessionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2123212ED29D008AB282 /* SessionError.swift */; };
0E0C2126212ED29D008AB282 /* SessionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2123212ED29D008AB282 /* SessionError.swift */; };
0E0C2127212ED29D008AB282 /* SessionProxy+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */; };
0E0C2128212ED29D008AB282 /* SessionProxy+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */; };
0E0C2125212ED29D008AB282 /* OpenVPNError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2123212ED29D008AB282 /* OpenVPNError.swift */; };
0E0C2126212ED29D008AB282 /* OpenVPNError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2123212ED29D008AB282 /* OpenVPNError.swift */; };
0E0C2127212ED29D008AB282 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2124212ED29D008AB282 /* Configuration.swift */; };
0E0C2128212ED29D008AB282 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0C2124212ED29D008AB282 /* Configuration.swift */; };
0E11089F1F77B9E800A92462 /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E17D7F91F730D9F009EE129 /* TunnelKit.framework */; };
0E1108AC1F77B9F900A92462 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AB1F77B9F900A92462 /* AppDelegate.swift */; };
0E1108AE1F77B9F900A92462 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1108AD1F77B9F900A92462 /* ViewController.swift */; };
@ -50,14 +45,12 @@
0E1108B61F77B9F900A92462 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1108B41F77B9F900A92462 /* LaunchScreen.storyboard */; };
0E12B29E21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B29D21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift */; };
0E12B29F21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B29D21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift */; };
0E12B2A32145341B00B4BAE9 /* PacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A22145341B00B4BAE9 /* PacketTests.swift */; };
0E12B2A521454F7F00B4BAE9 /* BidirectionalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A421454F7F00B4BAE9 /* BidirectionalState.swift */; };
0E12B2A621454F7F00B4BAE9 /* BidirectionalState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A421454F7F00B4BAE9 /* BidirectionalState.swift */; };
0E12B2A821456C0200B4BAE9 /* ControlChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */; };
0E12B2A921456C0200B4BAE9 /* ControlChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */; };
0E12B2AB2145E01700B4BAE9 /* ControlChannelSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */; };
0E12B2AC2145E01700B4BAE9 /* ControlChannelSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */; };
0E245D692135972800B012A2 /* PushTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E245D682135972800B012A2 /* PushTests.swift */; };
0E245D6C2137F73600B012A2 /* CompressionFramingNative.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E245D6B2137F73600B012A2 /* CompressionFramingNative.h */; };
0E39BCE8214B2AB60035E9DE /* ControlPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E39BCE6214B2AB60035E9DE /* ControlPacket.h */; };
0E39BCE9214B2AB60035E9DE /* ControlPacket.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E39BCE6214B2AB60035E9DE /* ControlPacket.h */; };
@ -71,8 +64,8 @@
0E3B65752249253B00EFF4DA /* tunnelbear.enc.1.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */; };
0E3B65762249253F00EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; };
0E3B65772249254000EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; };
0E3E0F212108A8CC00B371C1 /* SessionProxy+SessionReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+SessionReply.swift */; };
0E3E0F222108A8CC00B371C1 /* SessionProxy+SessionReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionProxy+SessionReply.swift */; };
0E3E0F212108A8CC00B371C1 /* PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* PushReply.swift */; };
0E3E0F222108A8CC00B371C1 /* PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* PushReply.swift */; };
0E411B9B2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; };
0E411B9C2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; };
0E411B9D2271F90700E0852C /* DNS.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E411B9A2271F90700E0852C /* DNS.m */; };
@ -85,7 +78,6 @@
0E48AC672271ADA9009B1A98 /* PacketStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E48AC632271ADA9009B1A98 /* PacketStream.m */; };
0E500EA622493B5B00CAE560 /* tunnelbear.enc.1.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E500EA522493B5B00CAE560 /* tunnelbear.enc.1.key */; };
0E500EA722493B5B00CAE560 /* tunnelbear.enc.1.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E500EA522493B5B00CAE560 /* tunnelbear.enc.1.key */; };
0E50D57521634E0A00FC87A8 /* ControlChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E50D57421634E0A00FC87A8 /* ControlChannelTests.swift */; };
0E58BF3322405410006FB157 /* lzoconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF2F22405410006FB157 /* lzoconf.h */; };
0E58BF3422405410006FB157 /* lzoconf.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF2F22405410006FB157 /* lzoconf.h */; };
0E58BF3522405410006FB157 /* lzodefs.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF3022405410006FB157 /* lzodefs.h */; };
@ -94,81 +86,24 @@
0E58BF3822405410006FB157 /* minilzo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF3122405410006FB157 /* minilzo.h */; };
0E58BF3922405410006FB157 /* minilzo.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF3222405410006FB157 /* minilzo.c */; };
0E58BF3A22405410006FB157 /* minilzo.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF3222405410006FB157 /* minilzo.c */; };
0E58BF3C2240547F006FB157 /* CompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF3B2240547F006FB157 /* CompressionTests.swift */; };
0E58BF3D2240547F006FB157 /* CompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF3B2240547F006FB157 /* CompressionTests.swift */; };
0E58BF4C22405C2F006FB157 /* StandardLZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF4922405C2F006FB157 /* StandardLZO.m */; };
0E58BF4D22405C2F006FB157 /* StandardLZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF4922405C2F006FB157 /* StandardLZO.m */; };
0E58BF502240F98F006FB157 /* CompressionAlgorithmNative.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF4F2240F98E006FB157 /* CompressionAlgorithmNative.h */; };
0E58BF512240F98F006FB157 /* CompressionAlgorithmNative.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF4F2240F98E006FB157 /* CompressionAlgorithmNative.h */; };
0E58BF532240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF522240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift */; };
0E58BF542240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF522240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift */; };
0E58BF532240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF522240FAA6006FB157 /* CompressionAlgorithm.swift */; };
0E58BF542240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF522240FAA6006FB157 /* CompressionAlgorithm.swift */; };
0E58BF5622411F3D006FB157 /* LZO.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF5522411F37006FB157 /* LZO.h */; };
0E58BF5722411F3E006FB157 /* LZO.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E58BF5522411F37006FB157 /* LZO.h */; };
0E58BF5922411FEF006FB157 /* LZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF5822411FEF006FB157 /* LZO.m */; };
0E58BF5A22411FEF006FB157 /* LZO.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BF5822411FEF006FB157 /* LZO.m */; };
0E58F1302138AC2F00A49F27 /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58F12F2138AC2F00A49F27 /* DNSTests.swift */; };
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 */; };
0E749F5F2178885500BB2701 /* OpenVPNSession+PIA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E749F5E2178885500BB2701 /* OpenVPNSession+PIA.swift */; };
0E749F602178885500BB2701 /* OpenVPNSession+PIA.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E749F5E2178885500BB2701 /* OpenVPNSession+PIA.swift */; };
0E749F622178911D00BB2701 /* pia-2048.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0E749F612178911C00BB2701 /* pia-2048.pem */; };
0E85A25A202CC5AF0059E9F9 /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */; };
0E9379C91F819A4300CE91B6 /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E17D7F91F730D9F009EE129 /* TunnelKit.framework */; };
0EA82A282190B220007960EB /* TunnelKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E3251C51F95770D00C108D9 /* TunnelKit.framework */; };
0EA82A2F2190B2B9007960EB /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */; };
0EA82A302190B2B9007960EB /* ControlChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E50D57421634E0A00FC87A8 /* ControlChannelTests.swift */; };
0EA82A312190B2B9007960EB /* DataManipulationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45420F0BB53004233D7 /* DataManipulationTests.swift */; };
0EA82A322190B2B9007960EB /* DataPathEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */; };
0EA82A332190B2B9007960EB /* DataPathPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B46020F0C0A4004233D7 /* DataPathPerformanceTests.swift */; };
0EA82A342190B2B9007960EB /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E58F12F2138AC2F00A49F27 /* DNSTests.swift */; };
0EA82A352190B2B9007960EB /* EncryptionPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45E20F0C098004233D7 /* EncryptionPerformanceTests.swift */; };
0EA82A362190B2B9007960EB /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */; };
0EA82A372190B2B9007960EB /* LinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45820F0BD9A004233D7 /* LinkTests.swift */; };
0EA82A382190B2B9007960EB /* PacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E12B2A22145341B00B4BAE9 /* PacketTests.swift */; };
0EA82A392190B2B9007960EB /* PushTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E245D682135972800B012A2 /* PushTests.swift */; };
0EA82A3A2190B2B9007960EB /* RandomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45620F0BD16004233D7 /* RandomTests.swift */; };
0EA82A3B2190B2B9007960EB /* RawPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */; };
0EA82A3C2190B2B9007960EB /* StaticKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E041D0B2152E80A0025FE3C /* StaticKeyTests.swift */; };
0EA82A3D2190B2B9007960EB /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */; };
0EA82A3E2190B2BC007960EB /* pia-2048.pem in Resources */ = {isa = PBXBuildFile; fileRef = 0E749F612178911C00BB2701 /* pia-2048.pem */; };
0EB03E202290D22A006D03A0 /* ConnectionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E102290D22A006D03A0 /* ConnectionStrategy.swift */; };
0EB03E212290D22A006D03A0 /* ConnectionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E102290D22A006D03A0 /* ConnectionStrategy.swift */; };
0EB03E222290D22A006D03A0 /* NETCPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E122290D22A006D03A0 /* NETCPInterface.swift */; };
0EB03E232290D22A006D03A0 /* NETCPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E122290D22A006D03A0 /* NETCPInterface.swift */; };
0EB03E242290D22A006D03A0 /* NETunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E132290D22A006D03A0 /* NETunnelInterface.swift */; };
0EB03E252290D22A006D03A0 /* NETunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E132290D22A006D03A0 /* NETunnelInterface.swift */; };
0EB03E262290D22A006D03A0 /* NWTCPConnectionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E142290D22A006D03A0 /* NWTCPConnectionState+Description.swift */; };
0EB03E272290D22A006D03A0 /* NWTCPConnectionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E142290D22A006D03A0 /* NWTCPConnectionState+Description.swift */; };
0EB03E282290D22A006D03A0 /* NEUDPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E152290D22A006D03A0 /* NEUDPInterface.swift */; };
0EB03E292290D22A006D03A0 /* NEUDPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E152290D22A006D03A0 /* NEUDPInterface.swift */; };
0EB03E2A2290D22A006D03A0 /* NWUDPSessionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E162290D22A006D03A0 /* NWUDPSessionState+Description.swift */; };
0EB03E2B2290D22A006D03A0 /* NWUDPSessionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E162290D22A006D03A0 /* NWUDPSessionState+Description.swift */; };
0EB03E2C2290D22A006D03A0 /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E172290D22A006D03A0 /* DNSResolver.swift */; };
0EB03E2D2290D22A006D03A0 /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E172290D22A006D03A0 /* DNSResolver.swift */; };
0EB03E2E2290D22A006D03A0 /* TunnelKitProvider+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E182290D22A006D03A0 /* TunnelKitProvider+Configuration.swift */; };
0EB03E2F2290D22A006D03A0 /* TunnelKitProvider+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E182290D22A006D03A0 /* TunnelKitProvider+Configuration.swift */; };
0EB03E302290D22A006D03A0 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E192290D22A006D03A0 /* Keychain.swift */; };
0EB03E312290D22A006D03A0 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E192290D22A006D03A0 /* Keychain.swift */; };
0EB03E322290D22A006D03A0 /* MemoryDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1A2290D22A006D03A0 /* MemoryDestination.swift */; };
0EB03E332290D22A006D03A0 /* MemoryDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1A2290D22A006D03A0 /* MemoryDestination.swift */; };
0EB03E342290D22A006D03A0 /* GenericSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1B2290D22A006D03A0 /* GenericSocket.swift */; };
0EB03E352290D22A006D03A0 /* GenericSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1B2290D22A006D03A0 /* GenericSocket.swift */; };
0EB03E362290D22A006D03A0 /* TunnelKitProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1C2290D22A006D03A0 /* TunnelKitProvider.swift */; };
0EB03E372290D22A006D03A0 /* TunnelKitProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1C2290D22A006D03A0 /* TunnelKitProvider.swift */; };
0EB03E382290D22A006D03A0 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1D2290D22A006D03A0 /* Utils.swift */; };
0EB03E392290D22A006D03A0 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1D2290D22A006D03A0 /* Utils.swift */; };
0EB03E3A2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1E2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift */; };
0EB03E3B2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1E2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift */; };
0EB03E3C2290D22A006D03A0 /* InterfaceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1F2290D22A006D03A0 /* InterfaceObserver.swift */; };
0EB03E3D2290D22A006D03A0 /* InterfaceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E1F2290D22A006D03A0 /* InterfaceObserver.swift */; };
0EB03E3F2290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E3E2290D310006D03A0 /* CoreConfiguration+OpenVPN.swift */; };
0EB03E402290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB03E3E2290D310006D03A0 /* CoreConfiguration+OpenVPN.swift */; };
0EB2B45320F0BB44004233D7 /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */; };
0EB2B45520F0BB53004233D7 /* DataManipulationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45420F0BB53004233D7 /* DataManipulationTests.swift */; };
0EB2B45720F0BD16004233D7 /* RandomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45620F0BD16004233D7 /* RandomTests.swift */; };
0EB2B45920F0BD9A004233D7 /* LinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45820F0BD9A004233D7 /* LinkTests.swift */; };
0EB2B45B20F0BE4C004233D7 /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */; };
0EB2B45D20F0BF41004233D7 /* RawPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */; };
0EB2B45F20F0C098004233D7 /* EncryptionPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B45E20F0C098004233D7 /* EncryptionPerformanceTests.swift */; };
0EB2B46120F0C0A4004233D7 /* DataPathPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB2B46020F0C0A4004233D7 /* DataPathPerformanceTests.swift */; };
0ECC60D82254981A0020BEAC /* ConfigurationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECC60D72254981A0020BEAC /* ConfigurationError.swift */; };
0ECC60D92254981A0020BEAC /* ConfigurationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECC60D72254981A0020BEAC /* ConfigurationError.swift */; };
0ECE3528212EB7770040F253 /* CryptoContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECE3527212EB7770040F253 /* CryptoContainer.swift */; };
@ -179,19 +114,90 @@
0ECEB1182252C8E900E9E551 /* tunnelbear.enc.8.key in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEB1142252C8E900E9E551 /* tunnelbear.enc.8.key */; };
0ECEB11B2252CDAD00E9E551 /* tunnelbear.crt in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEB11A2252CDAD00E9E551 /* tunnelbear.crt */; };
0ECEB11C2252CDAD00E9E551 /* tunnelbear.crt in Resources */ = {isa = PBXBuildFile; fileRef = 0ECEB11A2252CDAD00E9E551 /* tunnelbear.crt */; };
0ED9C8642138139000621BA3 /* SessionProxy+CompressionFraming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */; };
0ED9C8652138139000621BA3 /* SessionProxy+CompressionFraming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */; };
0ED9C8642138139000621BA3 /* CompressionFraming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED9C8632138139000621BA3 /* CompressionFraming.swift */; };
0ED9C8652138139000621BA3 /* CompressionFraming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED9C8632138139000621BA3 /* CompressionFraming.swift */; };
0EE2F96E2291636B00F56F49 /* IPv4Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F96D2291636B00F56F49 /* IPv4Settings.swift */; };
0EE2F96F2291636B00F56F49 /* IPv4Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F96D2291636B00F56F49 /* IPv4Settings.swift */; };
0EE2F9712291638600F56F49 /* IPv6Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9702291638600F56F49 /* IPv6Settings.swift */; };
0EE2F9722291638600F56F49 /* IPv6Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9702291638600F56F49 /* IPv6Settings.swift */; };
0EE2F974229163C900F56F49 /* Proxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F973229163C900F56F49 /* Proxy.swift */; };
0EE2F975229163C900F56F49 /* Proxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F973229163C900F56F49 /* Proxy.swift */; };
0EE2F97722916A5D00F56F49 /* OpenVPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F97622916A5D00F56F49 /* OpenVPN.swift */; };
0EE2F97822916A5D00F56F49 /* OpenVPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F97622916A5D00F56F49 /* OpenVPN.swift */; };
0EE2F97A2291817300F56F49 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9792291817300F56F49 /* Errors.swift */; };
0EE2F97B2291817300F56F49 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9792291817300F56F49 /* Errors.swift */; };
0EE2F9AC2291853D00F56F49 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9AB2291853D00F56F49 /* Session.swift */; };
0EE2F9AD2291853D00F56F49 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9AB2291853D00F56F49 /* Session.swift */; };
0EE2F9EE22918DA100F56F49 /* ConnectionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9DE22918DA100F56F49 /* ConnectionStrategy.swift */; };
0EE2F9EF22918DA100F56F49 /* ConnectionStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9DE22918DA100F56F49 /* ConnectionStrategy.swift */; };
0EE2F9F022918DA100F56F49 /* NETCPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E022918DA100F56F49 /* NETCPInterface.swift */; };
0EE2F9F122918DA100F56F49 /* NETCPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E022918DA100F56F49 /* NETCPInterface.swift */; };
0EE2F9F222918DA100F56F49 /* NETunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E122918DA100F56F49 /* NETunnelInterface.swift */; };
0EE2F9F322918DA100F56F49 /* NETunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E122918DA100F56F49 /* NETunnelInterface.swift */; };
0EE2F9F422918DA100F56F49 /* NWTCPConnectionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E222918DA100F56F49 /* NWTCPConnectionState+Description.swift */; };
0EE2F9F522918DA100F56F49 /* NWTCPConnectionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E222918DA100F56F49 /* NWTCPConnectionState+Description.swift */; };
0EE2F9F622918DA100F56F49 /* NEUDPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E322918DA100F56F49 /* NEUDPInterface.swift */; };
0EE2F9F722918DA100F56F49 /* NEUDPInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E322918DA100F56F49 /* NEUDPInterface.swift */; };
0EE2F9F822918DA100F56F49 /* NWUDPSessionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E422918DA100F56F49 /* NWUDPSessionState+Description.swift */; };
0EE2F9F922918DA100F56F49 /* NWUDPSessionState+Description.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E422918DA100F56F49 /* NWUDPSessionState+Description.swift */; };
0EE2F9FA22918DA100F56F49 /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E522918DA100F56F49 /* DNSResolver.swift */; };
0EE2F9FB22918DA100F56F49 /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E522918DA100F56F49 /* DNSResolver.swift */; };
0EE2F9FC22918DA100F56F49 /* TunnelKitProvider+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E622918DA100F56F49 /* TunnelKitProvider+Configuration.swift */; };
0EE2F9FD22918DA100F56F49 /* TunnelKitProvider+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E622918DA100F56F49 /* TunnelKitProvider+Configuration.swift */; };
0EE2F9FE22918DA100F56F49 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E722918DA100F56F49 /* Keychain.swift */; };
0EE2F9FF22918DA100F56F49 /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E722918DA100F56F49 /* Keychain.swift */; };
0EE2FA0022918DA100F56F49 /* MemoryDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E822918DA100F56F49 /* MemoryDestination.swift */; };
0EE2FA0122918DA100F56F49 /* MemoryDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E822918DA100F56F49 /* MemoryDestination.swift */; };
0EE2FA0222918DA100F56F49 /* GenericSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E922918DA100F56F49 /* GenericSocket.swift */; };
0EE2FA0322918DA100F56F49 /* GenericSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9E922918DA100F56F49 /* GenericSocket.swift */; };
0EE2FA0422918DA100F56F49 /* TunnelKitProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EA22918DA100F56F49 /* TunnelKitProvider.swift */; };
0EE2FA0522918DA100F56F49 /* TunnelKitProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EA22918DA100F56F49 /* TunnelKitProvider.swift */; };
0EE2FA0622918DA100F56F49 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EB22918DA100F56F49 /* Utils.swift */; };
0EE2FA0722918DA100F56F49 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EB22918DA100F56F49 /* Utils.swift */; };
0EE2FA0822918DA100F56F49 /* TunnelKitProvider+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EC22918DA100F56F49 /* TunnelKitProvider+Interaction.swift */; };
0EE2FA0922918DA100F56F49 /* TunnelKitProvider+Interaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9EC22918DA100F56F49 /* TunnelKitProvider+Interaction.swift */; };
0EE2FA0A22918DA100F56F49 /* InterfaceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9ED22918DA100F56F49 /* InterfaceObserver.swift */; };
0EE2FA0B22918DA100F56F49 /* InterfaceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2F9ED22918DA100F56F49 /* InterfaceObserver.swift */; };
0EE2FA422291954300F56F49 /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0E2291953300F56F49 /* AppExtensionTests.swift */; };
0EE2FA432291954300F56F49 /* CompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1C2291953300F56F49 /* CompressionTests.swift */; };
0EE2FA442291954300F56F49 /* ConfigurationParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA162291953300F56F49 /* ConfigurationParserTests.swift */; };
0EE2FA452291954300F56F49 /* ControlChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1A2291953300F56F49 /* ControlChannelTests.swift */; };
0EE2FA462291954300F56F49 /* DataManipulationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA192291953300F56F49 /* DataManipulationTests.swift */; };
0EE2FA472291954300F56F49 /* DataPathEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1D2291953300F56F49 /* DataPathEncryptionTests.swift */; };
0EE2FA482291954300F56F49 /* DataPathPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0D2291953300F56F49 /* DataPathPerformanceTests.swift */; };
0EE2FA492291954300F56F49 /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA112291953300F56F49 /* DNSTests.swift */; };
0EE2FA4A2291954300F56F49 /* EncryptionPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA172291953300F56F49 /* EncryptionPerformanceTests.swift */; };
0EE2FA4B2291954300F56F49 /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA102291953300F56F49 /* EncryptionTests.swift */; };
0EE2FA4C2291954300F56F49 /* LinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA122291953300F56F49 /* LinkTests.swift */; };
0EE2FA4D2291954300F56F49 /* PacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA182291953300F56F49 /* PacketTests.swift */; };
0EE2FA4E2291954300F56F49 /* PushTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1B2291953300F56F49 /* PushTests.swift */; };
0EE2FA4F2291954300F56F49 /* RandomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0F2291953300F56F49 /* RandomTests.swift */; };
0EE2FA502291954300F56F49 /* RawPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0C2291953300F56F49 /* RawPerformanceTests.swift */; };
0EE2FA512291954300F56F49 /* RoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA132291953300F56F49 /* RoutingTests.swift */; };
0EE2FA522291954300F56F49 /* StaticKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA142291953300F56F49 /* StaticKeyTests.swift */; };
0EE2FA532291954300F56F49 /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA152291953300F56F49 /* TestUtils.swift */; };
0EE2FA542291954400F56F49 /* AppExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0E2291953300F56F49 /* AppExtensionTests.swift */; };
0EE2FA552291954400F56F49 /* CompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1C2291953300F56F49 /* CompressionTests.swift */; };
0EE2FA562291954400F56F49 /* ConfigurationParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA162291953300F56F49 /* ConfigurationParserTests.swift */; };
0EE2FA572291954400F56F49 /* ControlChannelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1A2291953300F56F49 /* ControlChannelTests.swift */; };
0EE2FA582291954400F56F49 /* DataManipulationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA192291953300F56F49 /* DataManipulationTests.swift */; };
0EE2FA592291954400F56F49 /* DataPathEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1D2291953300F56F49 /* DataPathEncryptionTests.swift */; };
0EE2FA5A2291954400F56F49 /* DataPathPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0D2291953300F56F49 /* DataPathPerformanceTests.swift */; };
0EE2FA5B2291954400F56F49 /* DNSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA112291953300F56F49 /* DNSTests.swift */; };
0EE2FA5C2291954400F56F49 /* EncryptionPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA172291953300F56F49 /* EncryptionPerformanceTests.swift */; };
0EE2FA5D2291954400F56F49 /* EncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA102291953300F56F49 /* EncryptionTests.swift */; };
0EE2FA5E2291954400F56F49 /* LinkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA122291953300F56F49 /* LinkTests.swift */; };
0EE2FA5F2291954400F56F49 /* PacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA182291953300F56F49 /* PacketTests.swift */; };
0EE2FA602291954400F56F49 /* PushTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA1B2291953300F56F49 /* PushTests.swift */; };
0EE2FA612291954400F56F49 /* RandomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0F2291953300F56F49 /* RandomTests.swift */; };
0EE2FA622291954400F56F49 /* RawPerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA0C2291953300F56F49 /* RawPerformanceTests.swift */; };
0EE2FA632291954400F56F49 /* RoutingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA132291953300F56F49 /* RoutingTests.swift */; };
0EE2FA642291954400F56F49 /* StaticKeyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA142291953300F56F49 /* StaticKeyTests.swift */; };
0EE2FA652291954400F56F49 /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE2FA152291953300F56F49 /* TestUtils.swift */; };
0EE3B3E421471C3A0027AB17 /* StaticKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE3B3E321471C3A0027AB17 /* StaticKey.swift */; };
0EE3B3E521471C3A0027AB17 /* StaticKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE3B3E321471C3A0027AB17 /* StaticKey.swift */; };
0EE7A79820F6296F00B42E6A /* PacketMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EE7A79720F6296F00B42E6A /* PacketMacros.m */; };
0EE7A79920F6296F00B42E6A /* PacketMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EE7A79720F6296F00B42E6A /* PacketMacros.m */; };
0EE7A7A120F664AC00B42E6A /* DataPathEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */; };
0EEC49E120B5F7EA008FEB91 /* Allocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB42E2006D3C800F81029 /* Allocation.h */; };
0EEC49E220B5F7F6008FEB91 /* CryptoBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB4402006D3C800F81029 /* CryptoBox.h */; };
0EEC49E320B5F7F6008FEB91 /* DataPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB4352006D3C800F81029 /* DataPath.h */; };
@ -207,8 +213,8 @@
0EFB902A22788511006405E4 /* RoutingTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFB902722788511006405E4 /* RoutingTable.h */; };
0EFB902B22788512006405E4 /* RoutingTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFB902822788511006405E4 /* RoutingTable.m */; };
0EFB902C22788512006405E4 /* RoutingTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFB902822788511006405E4 /* RoutingTable.m */; };
0EFEB4552006D3C800F81029 /* SessionProxy+EncryptionBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */; };
0EFEB4562006D3C800F81029 /* SessionProxy+SessionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */; };
0EFEB4552006D3C800F81029 /* EncryptionBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42A2006D3C800F81029 /* EncryptionBridge.swift */; };
0EFEB4562006D3C800F81029 /* SessionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42B2006D3C800F81029 /* SessionKey.swift */; };
0EFEB4582006D3C800F81029 /* MSS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB42D2006D3C800F81029 /* MSS.h */; };
0EFEB4592006D3C800F81029 /* Allocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB42E2006D3C800F81029 /* Allocation.h */; };
0EFEB45A2006D3C800F81029 /* TunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42F2006D3C800F81029 /* TunnelInterface.swift */; };
@ -220,9 +226,9 @@
0EFEB4622006D3C800F81029 /* SecureRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4372006D3C800F81029 /* SecureRandom.swift */; };
0EFEB4632006D3C800F81029 /* ProtocolMacros.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */; };
0EFEB4642006D3C800F81029 /* ReplayProtector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB4392006D3C800F81029 /* ReplayProtector.h */; };
0EFEB4652006D3C800F81029 /* SessionProxy+Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43A2006D3C800F81029 /* SessionProxy+Authenticator.swift */; };
0EFEB4652006D3C800F81029 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43A2006D3C800F81029 /* Authenticator.swift */; };
0EFEB4662006D3C800F81029 /* ZeroingData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43B2006D3C800F81029 /* ZeroingData.swift */; };
0EFEB4672006D3C800F81029 /* SessionProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43C2006D3C800F81029 /* SessionProxy.swift */; };
0EFEB4672006D3C800F81029 /* OpenVPNSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43C2006D3C800F81029 /* OpenVPNSession.swift */; };
0EFEB4682006D3C800F81029 /* MSS.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43D2006D3C800F81029 /* MSS.m */; };
0EFEB4692006D3C800F81029 /* Packet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43E2006D3C800F81029 /* Packet.swift */; };
0EFEB46B2006D3C800F81029 /* CryptoBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EFEB4402006D3C800F81029 /* CryptoBox.h */; };
@ -236,17 +242,17 @@
0EFEB4742006D3C800F81029 /* CoreConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB44A2006D3C800F81029 /* CoreConfiguration.swift */; };
0EFEB4752006D3C800F81029 /* Errors.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB44B2006D3C800F81029 /* Errors.m */; };
0EFEB4762006D3C800F81029 /* DataPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB44C2006D3C800F81029 /* DataPath.m */; };
0EFEB48D2006D7F300F81029 /* SessionProxy+EncryptionBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */; };
0EFEB48E2006D7F300F81029 /* SessionProxy+SessionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */; };
0EFEB48D2006D7F300F81029 /* EncryptionBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42A2006D3C800F81029 /* EncryptionBridge.swift */; };
0EFEB48E2006D7F300F81029 /* SessionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42B2006D3C800F81029 /* SessionKey.swift */; };
0EFEB4902006D7F300F81029 /* TunnelInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB42F2006D3C800F81029 /* TunnelInterface.swift */; };
0EFEB4912006D7F300F81029 /* TLSBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4302006D3C800F81029 /* TLSBox.m */; };
0EFEB4922006D7F300F81029 /* ZeroingData.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4312006D3C800F81029 /* ZeroingData.m */; };
0EFEB4932006D7F300F81029 /* CryptoBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4322006D3C800F81029 /* CryptoBox.m */; };
0EFEB4952006D7F300F81029 /* SecureRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4372006D3C800F81029 /* SecureRandom.swift */; };
0EFEB4962006D7F300F81029 /* ProtocolMacros.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */; };
0EFEB4972006D7F300F81029 /* SessionProxy+Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43A2006D3C800F81029 /* SessionProxy+Authenticator.swift */; };
0EFEB4972006D7F300F81029 /* Authenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43A2006D3C800F81029 /* Authenticator.swift */; };
0EFEB4982006D7F300F81029 /* ZeroingData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43B2006D3C800F81029 /* ZeroingData.swift */; };
0EFEB4992006D7F300F81029 /* SessionProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43C2006D3C800F81029 /* SessionProxy.swift */; };
0EFEB4992006D7F300F81029 /* OpenVPNSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43C2006D3C800F81029 /* OpenVPNSession.swift */; };
0EFEB49A2006D7F300F81029 /* MSS.m in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43D2006D3C800F81029 /* MSS.m */; };
0EFEB49B2006D7F300F81029 /* Packet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB43E2006D3C800F81029 /* Packet.swift */; };
0EFEB49C2006D7F300F81029 /* Data+Manipulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFEB4432006D3C800F81029 /* Data+Manipulation.swift */; };
@ -297,22 +303,19 @@
/* Begin PBXFileReference section */
0E011F792196D93600BA59EE /* SocketType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketType.swift; sourceTree = "<group>"; };
0E011F7C2196D97200BA59EE /* EndpointProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EndpointProtocol.swift; sourceTree = "<group>"; };
0E011F7F2196E20300BA59EE /* ConfigurationParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationParserTests.swift; sourceTree = "<group>"; };
0E011F832196E25400BA59EE /* pia-hungary.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "pia-hungary.ovpn"; sourceTree = "<group>"; };
0E011F872196E2AB00BA59EE /* ConfigurationParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationParser.swift; sourceTree = "<group>"; };
0E041D082152E6FE0025FE3C /* SessionProxy+TLSWrap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+TLSWrap.swift"; sourceTree = "<group>"; };
0E041D0B2152E80A0025FE3C /* StaticKeyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticKeyTests.swift; sourceTree = "<group>"; };
0E041D082152E6FE0025FE3C /* TLSWrap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TLSWrap.swift; sourceTree = "<group>"; };
0E07595C20EF6D1400F38FD8 /* CryptoCBC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CryptoCBC.m; sourceTree = "<group>"; };
0E07596120EF733F00F38FD8 /* CryptoMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoMacros.h; sourceTree = "<group>"; };
0E07596A20EF79AB00F38FD8 /* Crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crypto.h; sourceTree = "<group>"; };
0E07596D20EF79B400F38FD8 /* CryptoCBC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoCBC.h; sourceTree = "<group>"; };
0E07597C20F0060E00F38FD8 /* CryptoAEAD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAEAD.h; sourceTree = "<group>"; };
0E07597D20F0060E00F38FD8 /* CryptoAEAD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoAEAD.m; sourceTree = "<group>"; };
0E0B203B227886AD007A3CB9 /* RoutingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingTests.swift; sourceTree = "<group>"; };
0E0B203E2278A85B007A3CB9 /* RoutingTableEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoutingTableEntry.h; sourceTree = "<group>"; };
0E0B203F2278A85B007A3CB9 /* RoutingTableEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoutingTableEntry.m; sourceTree = "<group>"; };
0E0C2123212ED29D008AB282 /* SessionError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionError.swift; sourceTree = "<group>"; };
0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+Configuration.swift"; sourceTree = "<group>"; };
0E0C2123212ED29D008AB282 /* OpenVPNError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenVPNError.swift; sourceTree = "<group>"; };
0E0C2124212ED29D008AB282 /* Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
0E11089A1F77B9E800A92462 /* TunnelKitTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TunnelKitTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0E11089E1F77B9E800A92462 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E1108A91F77B9F900A92462 /* TunnelKitHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TunnelKitHost.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -323,12 +326,10 @@
0E1108B51F77B9F900A92462 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
0E1108B71F77B9F900A92462 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E12B29D21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+Shortcuts.swift"; sourceTree = "<group>"; };
0E12B2A22145341B00B4BAE9 /* PacketTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketTests.swift; sourceTree = "<group>"; };
0E12B2A421454F7F00B4BAE9 /* BidirectionalState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BidirectionalState.swift; sourceTree = "<group>"; };
0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlChannel.swift; sourceTree = "<group>"; };
0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlChannelSerializer.swift; sourceTree = "<group>"; };
0E17D7F91F730D9F009EE129 /* TunnelKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TunnelKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0E245D682135972800B012A2 /* PushTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushTests.swift; sourceTree = "<group>"; };
0E245D6B2137F73600B012A2 /* CompressionFramingNative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressionFramingNative.h; sourceTree = "<group>"; };
0E3251C51F95770D00C108D9 /* TunnelKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TunnelKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0E39BCE6214B2AB60035E9DE /* ControlPacket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControlPacket.h; sourceTree = "<group>"; };
@ -337,7 +338,7 @@
0E3B15C62152B05E00984B17 /* CryptoCTR.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoCTR.m; sourceTree = "<group>"; };
0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.enc.1.ovpn; sourceTree = "<group>"; };
0E3B65712249247E00EFF4DA /* tunnelbear.key */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.key; sourceTree = "<group>"; };
0E3E0F202108A8CC00B371C1 /* SessionProxy+SessionReply.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+SessionReply.swift"; sourceTree = "<group>"; };
0E3E0F202108A8CC00B371C1 /* PushReply.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushReply.swift; sourceTree = "<group>"; };
0E411B992271F90700E0852C /* DNS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DNS.h; sourceTree = "<group>"; };
0E411B9A2271F90700E0852C /* DNS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DNS.m; sourceTree = "<group>"; };
0E411B9F2271FA3300E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; };
@ -345,70 +346,78 @@
0E48AC622271ADA8009B1A98 /* PacketStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketStream.h; sourceTree = "<group>"; };
0E48AC632271ADA9009B1A98 /* PacketStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PacketStream.m; sourceTree = "<group>"; };
0E500EA522493B5B00CAE560 /* tunnelbear.enc.1.key */ = {isa = PBXFileReference; lastKnownFileType = text; path = tunnelbear.enc.1.key; sourceTree = "<group>"; };
0E50D57421634E0A00FC87A8 /* ControlChannelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlChannelTests.swift; sourceTree = "<group>"; };
0E58BF2F22405410006FB157 /* lzoconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lzoconf.h; sourceTree = "<group>"; };
0E58BF3022405410006FB157 /* lzodefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lzodefs.h; sourceTree = "<group>"; };
0E58BF3122405410006FB157 /* minilzo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = minilzo.h; sourceTree = "<group>"; };
0E58BF3222405410006FB157 /* minilzo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = minilzo.c; sourceTree = "<group>"; };
0E58BF3B2240547F006FB157 /* CompressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompressionTests.swift; sourceTree = "<group>"; };
0E58BF4922405C2F006FB157 /* StandardLZO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StandardLZO.m; sourceTree = "<group>"; };
0E58BF4F2240F98E006FB157 /* CompressionAlgorithmNative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressionAlgorithmNative.h; sourceTree = "<group>"; };
0E58BF522240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+CompressionAlgorithm.swift"; sourceTree = "<group>"; };
0E58BF522240FAA6006FB157 /* CompressionAlgorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompressionAlgorithm.swift; sourceTree = "<group>"; };
0E58BF5522411F37006FB157 /* LZO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LZO.h; sourceTree = "<group>"; };
0E58BF5822411FEF006FB157 /* LZO.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LZO.m; 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>"; };
0E6479E0212EACD6008E6888 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+PIA.swift"; sourceTree = "<group>"; };
0E749F5E2178885500BB2701 /* OpenVPNSession+PIA.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenVPNSession+PIA.swift"; sourceTree = "<group>"; };
0E749F612178911C00BB2701 /* pia-2048.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = "pia-2048.pem"; 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>"; };
0EA82A232190B220007960EB /* TunnelKitTests-macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TunnelKitTests-macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0EA82A272190B220007960EB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0EB03E0E2290CF52006D03A0 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
0EB03E102290D22A006D03A0 /* ConnectionStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionStrategy.swift; sourceTree = "<group>"; };
0EB03E122290D22A006D03A0 /* NETCPInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NETCPInterface.swift; sourceTree = "<group>"; };
0EB03E132290D22A006D03A0 /* NETunnelInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NETunnelInterface.swift; sourceTree = "<group>"; };
0EB03E142290D22A006D03A0 /* NWTCPConnectionState+Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NWTCPConnectionState+Description.swift"; sourceTree = "<group>"; };
0EB03E152290D22A006D03A0 /* NEUDPInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NEUDPInterface.swift; sourceTree = "<group>"; };
0EB03E162290D22A006D03A0 /* NWUDPSessionState+Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NWUDPSessionState+Description.swift"; sourceTree = "<group>"; };
0EB03E172290D22A006D03A0 /* DNSResolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSResolver.swift; sourceTree = "<group>"; };
0EB03E182290D22A006D03A0 /* TunnelKitProvider+Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+Configuration.swift"; sourceTree = "<group>"; };
0EB03E192290D22A006D03A0 /* Keychain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = "<group>"; };
0EB03E1A2290D22A006D03A0 /* MemoryDestination.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryDestination.swift; sourceTree = "<group>"; };
0EB03E1B2290D22A006D03A0 /* GenericSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericSocket.swift; sourceTree = "<group>"; };
0EB03E1C2290D22A006D03A0 /* TunnelKitProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelKitProvider.swift; sourceTree = "<group>"; };
0EB03E1D2290D22A006D03A0 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
0EB03E1E2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+Interaction.swift"; sourceTree = "<group>"; };
0EB03E1F2290D22A006D03A0 /* InterfaceObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceObserver.swift; sourceTree = "<group>"; };
0EB03E3E2290D310006D03A0 /* CoreConfiguration+OpenVPN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreConfiguration+OpenVPN.swift"; sourceTree = "<group>"; };
0EB03E412291542C006D03A0 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionTests.swift; sourceTree = "<group>"; };
0EB2B45420F0BB53004233D7 /* DataManipulationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManipulationTests.swift; sourceTree = "<group>"; };
0EB2B45620F0BD16004233D7 /* RandomTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomTests.swift; sourceTree = "<group>"; };
0EB2B45820F0BD9A004233D7 /* LinkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkTests.swift; sourceTree = "<group>"; };
0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestUtils.swift; sourceTree = "<group>"; };
0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawPerformanceTests.swift; sourceTree = "<group>"; };
0EB2B45E20F0C098004233D7 /* EncryptionPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionPerformanceTests.swift; sourceTree = "<group>"; };
0EB2B46020F0C0A4004233D7 /* DataPathPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataPathPerformanceTests.swift; sourceTree = "<group>"; };
0ECC60D72254981A0020BEAC /* ConfigurationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationError.swift; sourceTree = "<group>"; };
0ECE3527212EB7770040F253 /* CryptoContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptoContainer.swift; sourceTree = "<group>"; };
0ECEB1132252C8E900E9E551 /* tunnelbear.enc.8.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.enc.8.ovpn; sourceTree = "<group>"; };
0ECEB1142252C8E900E9E551 /* tunnelbear.enc.8.key */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.enc.8.key; sourceTree = "<group>"; };
0ECEB11A2252CDAD00E9E551 /* tunnelbear.crt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.crt; sourceTree = "<group>"; };
0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SessionProxy+CompressionFraming.swift"; sourceTree = "<group>"; };
0ED9C8632138139000621BA3 /* CompressionFraming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompressionFraming.swift; sourceTree = "<group>"; };
0EE2F96D2291636B00F56F49 /* IPv4Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv4Settings.swift; sourceTree = "<group>"; };
0EE2F9702291638600F56F49 /* IPv6Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv6Settings.swift; sourceTree = "<group>"; };
0EE2F973229163C900F56F49 /* Proxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Proxy.swift; sourceTree = "<group>"; };
0EE2F97622916A5D00F56F49 /* OpenVPN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPN.swift; sourceTree = "<group>"; };
0EE2F9792291817300F56F49 /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
0EE2F9AB2291853D00F56F49 /* Session.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Session.swift; sourceTree = "<group>"; };
0EE2F9DE22918DA100F56F49 /* ConnectionStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionStrategy.swift; sourceTree = "<group>"; };
0EE2F9E022918DA100F56F49 /* NETCPInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NETCPInterface.swift; sourceTree = "<group>"; };
0EE2F9E122918DA100F56F49 /* NETunnelInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NETunnelInterface.swift; sourceTree = "<group>"; };
0EE2F9E222918DA100F56F49 /* NWTCPConnectionState+Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NWTCPConnectionState+Description.swift"; sourceTree = "<group>"; };
0EE2F9E322918DA100F56F49 /* NEUDPInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NEUDPInterface.swift; sourceTree = "<group>"; };
0EE2F9E422918DA100F56F49 /* NWUDPSessionState+Description.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NWUDPSessionState+Description.swift"; sourceTree = "<group>"; };
0EE2F9E522918DA100F56F49 /* DNSResolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSResolver.swift; sourceTree = "<group>"; };
0EE2F9E622918DA100F56F49 /* TunnelKitProvider+Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+Configuration.swift"; sourceTree = "<group>"; };
0EE2F9E722918DA100F56F49 /* Keychain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = "<group>"; };
0EE2F9E822918DA100F56F49 /* MemoryDestination.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryDestination.swift; sourceTree = "<group>"; };
0EE2F9E922918DA100F56F49 /* GenericSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GenericSocket.swift; sourceTree = "<group>"; };
0EE2F9EA22918DA100F56F49 /* TunnelKitProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelKitProvider.swift; sourceTree = "<group>"; };
0EE2F9EB22918DA100F56F49 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
0EE2F9EC22918DA100F56F49 /* TunnelKitProvider+Interaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TunnelKitProvider+Interaction.swift"; sourceTree = "<group>"; };
0EE2F9ED22918DA100F56F49 /* InterfaceObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterfaceObserver.swift; sourceTree = "<group>"; };
0EE2FA0C2291953300F56F49 /* RawPerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawPerformanceTests.swift; sourceTree = "<group>"; };
0EE2FA0D2291953300F56F49 /* DataPathPerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataPathPerformanceTests.swift; sourceTree = "<group>"; };
0EE2FA0E2291953300F56F49 /* AppExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppExtensionTests.swift; sourceTree = "<group>"; };
0EE2FA0F2291953300F56F49 /* RandomTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomTests.swift; sourceTree = "<group>"; };
0EE2FA102291953300F56F49 /* EncryptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EncryptionTests.swift; sourceTree = "<group>"; };
0EE2FA112291953300F56F49 /* DNSTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DNSTests.swift; sourceTree = "<group>"; };
0EE2FA122291953300F56F49 /* LinkTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkTests.swift; sourceTree = "<group>"; };
0EE2FA132291953300F56F49 /* RoutingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoutingTests.swift; sourceTree = "<group>"; };
0EE2FA142291953300F56F49 /* StaticKeyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticKeyTests.swift; sourceTree = "<group>"; };
0EE2FA152291953300F56F49 /* TestUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUtils.swift; sourceTree = "<group>"; };
0EE2FA162291953300F56F49 /* ConfigurationParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationParserTests.swift; sourceTree = "<group>"; };
0EE2FA172291953300F56F49 /* EncryptionPerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EncryptionPerformanceTests.swift; sourceTree = "<group>"; };
0EE2FA182291953300F56F49 /* PacketTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketTests.swift; sourceTree = "<group>"; };
0EE2FA192291953300F56F49 /* DataManipulationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataManipulationTests.swift; sourceTree = "<group>"; };
0EE2FA1A2291953300F56F49 /* ControlChannelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlChannelTests.swift; sourceTree = "<group>"; };
0EE2FA1B2291953300F56F49 /* PushTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushTests.swift; sourceTree = "<group>"; };
0EE2FA1C2291953300F56F49 /* CompressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompressionTests.swift; sourceTree = "<group>"; };
0EE2FA1D2291953300F56F49 /* DataPathEncryptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataPathEncryptionTests.swift; sourceTree = "<group>"; };
0EE3B3E321471C3A0027AB17 /* StaticKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticKey.swift; sourceTree = "<group>"; };
0EE7A79420F61EDC00B42E6A /* PacketMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketMacros.h; sourceTree = "<group>"; };
0EE7A79720F6296F00B42E6A /* PacketMacros.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PacketMacros.m; sourceTree = "<group>"; };
0EE7A79D20F6488400B42E6A /* DataPathCrypto.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataPathCrypto.h; sourceTree = "<group>"; };
0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataPathEncryptionTests.swift; sourceTree = "<group>"; };
0EFB902722788511006405E4 /* RoutingTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoutingTable.h; sourceTree = "<group>"; };
0EFB902822788511006405E4 /* RoutingTable.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoutingTable.m; sourceTree = "<group>"; };
0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+EncryptionBridge.swift"; sourceTree = "<group>"; };
0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+SessionKey.swift"; sourceTree = "<group>"; };
0EFEB42A2006D3C800F81029 /* EncryptionBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EncryptionBridge.swift; sourceTree = "<group>"; };
0EFEB42B2006D3C800F81029 /* SessionKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionKey.swift; sourceTree = "<group>"; };
0EFEB42D2006D3C800F81029 /* MSS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MSS.h; sourceTree = "<group>"; };
0EFEB42E2006D3C800F81029 /* Allocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Allocation.h; sourceTree = "<group>"; };
0EFEB42F2006D3C800F81029 /* TunnelInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelInterface.swift; sourceTree = "<group>"; };
@ -420,9 +429,9 @@
0EFEB4372006D3C800F81029 /* SecureRandom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecureRandom.swift; sourceTree = "<group>"; };
0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProtocolMacros.swift; sourceTree = "<group>"; };
0EFEB4392006D3C800F81029 /* ReplayProtector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReplayProtector.h; sourceTree = "<group>"; };
0EFEB43A2006D3C800F81029 /* SessionProxy+Authenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SessionProxy+Authenticator.swift"; sourceTree = "<group>"; };
0EFEB43A2006D3C800F81029 /* Authenticator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Authenticator.swift; sourceTree = "<group>"; };
0EFEB43B2006D3C800F81029 /* ZeroingData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZeroingData.swift; sourceTree = "<group>"; };
0EFEB43C2006D3C800F81029 /* SessionProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SessionProxy.swift; sourceTree = "<group>"; };
0EFEB43C2006D3C800F81029 /* OpenVPNSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenVPNSession.swift; sourceTree = "<group>"; };
0EFEB43D2006D3C800F81029 /* MSS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MSS.m; sourceTree = "<group>"; };
0EFEB43E2006D3C800F81029 /* Packet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Packet.swift; sourceTree = "<group>"; };
0EFEB4402006D3C800F81029 /* CryptoBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoBox.h; sourceTree = "<group>"; };
@ -502,24 +511,24 @@
0E11089B1F77B9E800A92462 /* TunnelKitTests */ = {
isa = PBXGroup;
children = (
0E85A259202CC5AE0059E9F9 /* AppExtensionTests.swift */,
0E58BF3B2240547F006FB157 /* CompressionTests.swift */,
0E011F7F2196E20300BA59EE /* ConfigurationParserTests.swift */,
0E50D57421634E0A00FC87A8 /* ControlChannelTests.swift */,
0EB2B45420F0BB53004233D7 /* DataManipulationTests.swift */,
0EE7A7A020F664AB00B42E6A /* DataPathEncryptionTests.swift */,
0EB2B46020F0C0A4004233D7 /* DataPathPerformanceTests.swift */,
0E58F12F2138AC2F00A49F27 /* DNSTests.swift */,
0EB2B45E20F0C098004233D7 /* EncryptionPerformanceTests.swift */,
0EB2B45220F0BB44004233D7 /* EncryptionTests.swift */,
0EB2B45820F0BD9A004233D7 /* LinkTests.swift */,
0E12B2A22145341B00B4BAE9 /* PacketTests.swift */,
0E245D682135972800B012A2 /* PushTests.swift */,
0EB2B45620F0BD16004233D7 /* RandomTests.swift */,
0EB2B45C20F0BF41004233D7 /* RawPerformanceTests.swift */,
0E0B203B227886AD007A3CB9 /* RoutingTests.swift */,
0E041D0B2152E80A0025FE3C /* StaticKeyTests.swift */,
0EB2B45A20F0BE4C004233D7 /* TestUtils.swift */,
0EE2FA0E2291953300F56F49 /* AppExtensionTests.swift */,
0EE2FA1C2291953300F56F49 /* CompressionTests.swift */,
0EE2FA162291953300F56F49 /* ConfigurationParserTests.swift */,
0EE2FA1A2291953300F56F49 /* ControlChannelTests.swift */,
0EE2FA192291953300F56F49 /* DataManipulationTests.swift */,
0EE2FA1D2291953300F56F49 /* DataPathEncryptionTests.swift */,
0EE2FA0D2291953300F56F49 /* DataPathPerformanceTests.swift */,
0EE2FA112291953300F56F49 /* DNSTests.swift */,
0EE2FA172291953300F56F49 /* EncryptionPerformanceTests.swift */,
0EE2FA102291953300F56F49 /* EncryptionTests.swift */,
0EE2FA122291953300F56F49 /* LinkTests.swift */,
0EE2FA182291953300F56F49 /* PacketTests.swift */,
0EE2FA1B2291953300F56F49 /* PushTests.swift */,
0EE2FA0F2291953300F56F49 /* RandomTests.swift */,
0EE2FA0C2291953300F56F49 /* RawPerformanceTests.swift */,
0EE2FA132291953300F56F49 /* RoutingTests.swift */,
0EE2FA142291953300F56F49 /* StaticKeyTests.swift */,
0EE2FA152291953300F56F49 /* TestUtils.swift */,
0E749F612178911C00BB2701 /* pia-2048.pem */,
0E011F832196E25400BA59EE /* pia-hungary.ovpn */,
0ECEB11A2252CDAD00E9E551 /* tunnelbear.crt */,
@ -585,7 +594,7 @@
0E17D8041F730DDD009EE129 /* Sources */ = {
isa = PBXGroup;
children = (
0EB03E0F2290D22A006D03A0 /* AppExtension */,
0EE2F9DD22918DA100F56F49 /* AppExtension */,
0EFEB4292006D3C800F81029 /* Core */,
0E58BEDC2240521F006FB157 /* LZO */,
0EB03E0A2290A338006D03A0 /* OpenVPN */,
@ -648,8 +657,12 @@
0EB03E0A2290A338006D03A0 /* OpenVPN */ = {
isa = PBXGroup;
children = (
0EFEB43A2006D3C800F81029 /* Authenticator.swift */,
0E58BF522240FAA6006FB157 /* CompressionAlgorithm.swift */,
0E58BF4F2240F98E006FB157 /* CompressionAlgorithmNative.h */,
0ED9C8632138139000621BA3 /* CompressionFraming.swift */,
0E245D6B2137F73600B012A2 /* CompressionFramingNative.h */,
0E0C2124212ED29D008AB282 /* Configuration.swift */,
0E011F872196E2AB00BA59EE /* ConfigurationParser.swift */,
0E12B2A721456C0200B4BAE9 /* ControlChannel.swift */,
0E12B2AA2145E01700B4BAE9 /* ControlChannelSerializer.swift */,
@ -670,61 +683,58 @@
0EFEB4352006D3C800F81029 /* DataPath.h */,
0EFEB44C2006D3C800F81029 /* DataPath.m */,
0EE7A79D20F6488400B42E6A /* DataPathCrypto.h */,
0EFEB42A2006D3C800F81029 /* EncryptionBridge.swift */,
0EB03E412291542C006D03A0 /* module.modulemap */,
0EFEB42D2006D3C800F81029 /* MSS.h */,
0EFEB43D2006D3C800F81029 /* MSS.m */,
0EE2F97622916A5D00F56F49 /* OpenVPN.swift */,
0E0C2123212ED29D008AB282 /* OpenVPNError.swift */,
0EFEB43C2006D3C800F81029 /* OpenVPNSession.swift */,
0E749F5E2178885500BB2701 /* OpenVPNSession+PIA.swift */,
0EFEB43E2006D3C800F81029 /* Packet.swift */,
0EE7A79420F61EDC00B42E6A /* PacketMacros.h */,
0EE7A79720F6296F00B42E6A /* PacketMacros.m */,
0E48AC622271ADA8009B1A98 /* PacketStream.h */,
0E48AC632271ADA9009B1A98 /* PacketStream.m */,
0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */,
0E3E0F202108A8CC00B371C1 /* PushReply.swift */,
0EFEB4392006D3C800F81029 /* ReplayProtector.h */,
0EFEB4482006D3C800F81029 /* ReplayProtector.m */,
0E0C2123212ED29D008AB282 /* SessionError.swift */,
0EFEB43C2006D3C800F81029 /* SessionProxy.swift */,
0EFEB43A2006D3C800F81029 /* SessionProxy+Authenticator.swift */,
0E58BF522240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift */,
0ED9C8632138139000621BA3 /* SessionProxy+CompressionFraming.swift */,
0E0C2124212ED29D008AB282 /* SessionProxy+Configuration.swift */,
0EFEB42A2006D3C800F81029 /* SessionProxy+EncryptionBridge.swift */,
0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */,
0EFEB42B2006D3C800F81029 /* SessionProxy+SessionKey.swift */,
0E3E0F202108A8CC00B371C1 /* SessionProxy+SessionReply.swift */,
0E041D082152E6FE0025FE3C /* SessionProxy+TLSWrap.swift */,
0EFEB42B2006D3C800F81029 /* SessionKey.swift */,
0EE3B3E321471C3A0027AB17 /* StaticKey.swift */,
0EFEB4442006D3C800F81029 /* TLSBox.h */,
0EFEB4302006D3C800F81029 /* TLSBox.m */,
0E041D082152E6FE0025FE3C /* TLSWrap.swift */,
);
path = OpenVPN;
sourceTree = "<group>";
};
0EB03E0F2290D22A006D03A0 /* AppExtension */ = {
0EE2F9DD22918DA100F56F49 /* AppExtension */ = {
isa = PBXGroup;
children = (
0EB03E112290D22A006D03A0 /* Transport */,
0EB03E102290D22A006D03A0 /* ConnectionStrategy.swift */,
0EB03E172290D22A006D03A0 /* DNSResolver.swift */,
0EB03E1B2290D22A006D03A0 /* GenericSocket.swift */,
0EB03E1F2290D22A006D03A0 /* InterfaceObserver.swift */,
0EB03E192290D22A006D03A0 /* Keychain.swift */,
0EB03E1A2290D22A006D03A0 /* MemoryDestination.swift */,
0EB03E1C2290D22A006D03A0 /* TunnelKitProvider.swift */,
0EB03E182290D22A006D03A0 /* TunnelKitProvider+Configuration.swift */,
0EB03E1E2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift */,
0EB03E1D2290D22A006D03A0 /* Utils.swift */,
0EE2F9DF22918DA100F56F49 /* Transport */,
0EE2F9DE22918DA100F56F49 /* ConnectionStrategy.swift */,
0EE2F9E522918DA100F56F49 /* DNSResolver.swift */,
0EE2F9E922918DA100F56F49 /* GenericSocket.swift */,
0EE2F9ED22918DA100F56F49 /* InterfaceObserver.swift */,
0EE2F9E722918DA100F56F49 /* Keychain.swift */,
0EE2F9E822918DA100F56F49 /* MemoryDestination.swift */,
0EE2F9EA22918DA100F56F49 /* TunnelKitProvider.swift */,
0EE2F9E622918DA100F56F49 /* TunnelKitProvider+Configuration.swift */,
0EE2F9EC22918DA100F56F49 /* TunnelKitProvider+Interaction.swift */,
0EE2F9EB22918DA100F56F49 /* Utils.swift */,
);
path = AppExtension;
sourceTree = "<group>";
};
0EB03E112290D22A006D03A0 /* Transport */ = {
0EE2F9DF22918DA100F56F49 /* Transport */ = {
isa = PBXGroup;
children = (
0EB03E122290D22A006D03A0 /* NETCPInterface.swift */,
0EB03E132290D22A006D03A0 /* NETunnelInterface.swift */,
0EB03E142290D22A006D03A0 /* NWTCPConnectionState+Description.swift */,
0EB03E152290D22A006D03A0 /* NEUDPInterface.swift */,
0EB03E162290D22A006D03A0 /* NWUDPSessionState+Description.swift */,
0EE2F9E022918DA100F56F49 /* NETCPInterface.swift */,
0EE2F9E122918DA100F56F49 /* NETunnelInterface.swift */,
0EE2F9E222918DA100F56F49 /* NWTCPConnectionState+Description.swift */,
0EE2F9E322918DA100F56F49 /* NEUDPInterface.swift */,
0EE2F9E422918DA100F56F49 /* NWUDPSessionState+Description.swift */,
);
path = Transport;
sourceTree = "<group>";
@ -743,6 +753,7 @@
0E011F7C2196D97200BA59EE /* EndpointProtocol.swift */,
0EFEB4362006D3C800F81029 /* Errors.h */,
0EFEB44B2006D3C800F81029 /* Errors.m */,
0EE2F9792291817300F56F49 /* Errors.swift */,
0EFEB4452006D3C800F81029 /* IOInterface.swift */,
0EE2F96D2291636B00F56F49 /* IPv4Settings.swift */,
0EE2F9702291638600F56F49 /* IPv6Settings.swift */,
@ -757,6 +768,7 @@
0E0B203E2278A85B007A3CB9 /* RoutingTableEntry.h */,
0E0B203F2278A85B007A3CB9 /* RoutingTableEntry.m */,
0EFEB4372006D3C800F81029 /* SecureRandom.swift */,
0EE2F9AB2291853D00F56F49 /* Session.swift */,
0E011F792196D93600BA59EE /* SocketType.swift */,
0EFEB42F2006D3C800F81029 /* TunnelInterface.swift */,
0EFEB4412006D3C800F81029 /* ZeroingData.h */,
@ -1223,24 +1235,24 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0EB2B45720F0BD16004233D7 /* RandomTests.swift in Sources */,
0E011F812196E23700BA59EE /* ConfigurationParserTests.swift in Sources */,
0EB2B45920F0BD9A004233D7 /* LinkTests.swift in Sources */,
0EB2B45520F0BB53004233D7 /* DataManipulationTests.swift in Sources */,
0E50D57521634E0A00FC87A8 /* ControlChannelTests.swift in Sources */,
0EB2B45320F0BB44004233D7 /* EncryptionTests.swift in Sources */,
0EB2B45B20F0BE4C004233D7 /* TestUtils.swift in Sources */,
0E58F1302138AC2F00A49F27 /* DNSTests.swift in Sources */,
0E12B2A32145341B00B4BAE9 /* PacketTests.swift in Sources */,
0E041D0C2152E80A0025FE3C /* StaticKeyTests.swift in Sources */,
0E245D692135972800B012A2 /* PushTests.swift in Sources */,
0EB2B46120F0C0A4004233D7 /* DataPathPerformanceTests.swift in Sources */,
0E0B203C227886AD007A3CB9 /* RoutingTests.swift in Sources */,
0EB2B45F20F0C098004233D7 /* EncryptionPerformanceTests.swift in Sources */,
0EE7A7A120F664AC00B42E6A /* DataPathEncryptionTests.swift in Sources */,
0EB2B45D20F0BF41004233D7 /* RawPerformanceTests.swift in Sources */,
0E85A25A202CC5AF0059E9F9 /* AppExtensionTests.swift in Sources */,
0E58BF3C2240547F006FB157 /* CompressionTests.swift in Sources */,
0EE2FA522291954300F56F49 /* StaticKeyTests.swift in Sources */,
0EE2FA432291954300F56F49 /* CompressionTests.swift in Sources */,
0EE2FA492291954300F56F49 /* DNSTests.swift in Sources */,
0EE2FA472291954300F56F49 /* DataPathEncryptionTests.swift in Sources */,
0EE2FA502291954300F56F49 /* RawPerformanceTests.swift in Sources */,
0EE2FA4D2291954300F56F49 /* PacketTests.swift in Sources */,
0EE2FA452291954300F56F49 /* ControlChannelTests.swift in Sources */,
0EE2FA4E2291954300F56F49 /* PushTests.swift in Sources */,
0EE2FA422291954300F56F49 /* AppExtensionTests.swift in Sources */,
0EE2FA512291954300F56F49 /* RoutingTests.swift in Sources */,
0EE2FA4A2291954300F56F49 /* EncryptionPerformanceTests.swift in Sources */,
0EE2FA4F2291954300F56F49 /* RandomTests.swift in Sources */,
0EE2FA4B2291954300F56F49 /* EncryptionTests.swift in Sources */,
0EE2FA532291954300F56F49 /* TestUtils.swift in Sources */,
0EE2FA462291954300F56F49 /* DataManipulationTests.swift in Sources */,
0EE2FA4C2291954300F56F49 /* LinkTests.swift in Sources */,
0EE2FA442291954300F56F49 /* ConfigurationParserTests.swift in Sources */,
0EE2FA482291954300F56F49 /* DataPathPerformanceTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1257,75 +1269,78 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0EB03E202290D22A006D03A0 /* ConnectionStrategy.swift in Sources */,
0EB03E322290D22A006D03A0 /* MemoryDestination.swift in Sources */,
0E58BF4C22405C2F006FB157 /* StandardLZO.m in Sources */,
0EB03E222290D22A006D03A0 /* NETCPInterface.swift in Sources */,
0EE2F974229163C900F56F49 /* Proxy.swift in Sources */,
0EFEB4732006D3C800F81029 /* LinkInterface.swift in Sources */,
0EFEB4652006D3C800F81029 /* SessionProxy+Authenticator.swift in Sources */,
0EFEB4652006D3C800F81029 /* Authenticator.swift in Sources */,
0EE2F9F222918DA100F56F49 /* NETunnelInterface.swift in Sources */,
0EE2F9FE22918DA100F56F49 /* Keychain.swift in Sources */,
0EE7A79820F6296F00B42E6A /* PacketMacros.m in Sources */,
0EB03E282290D22A006D03A0 /* NEUDPInterface.swift in Sources */,
0EB03E2C2290D22A006D03A0 /* DNSResolver.swift in Sources */,
0EFEB4562006D3C800F81029 /* SessionProxy+SessionKey.swift in Sources */,
0EFEB4562006D3C800F81029 /* SessionKey.swift in Sources */,
0E0B20422278A85C007A3CB9 /* RoutingTableEntry.m in Sources */,
0E58BF5922411FEF006FB157 /* LZO.m in Sources */,
0E12B29E21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift in Sources */,
0E749F5F2178885500BB2701 /* SessionProxy+PIA.swift in Sources */,
0EE2F9F822918DA100F56F49 /* NWUDPSessionState+Description.swift in Sources */,
0E749F5F2178885500BB2701 /* OpenVPNSession+PIA.swift in Sources */,
0EE3B3E421471C3A0027AB17 /* StaticKey.swift in Sources */,
0EE2F9AC2291853D00F56F49 /* Session.swift in Sources */,
0EFEB4622006D3C800F81029 /* SecureRandom.swift in Sources */,
0EFEB45D2006D3C800F81029 /* CryptoBox.m in Sources */,
0E3B15C92152B05E00984B17 /* CryptoCTR.m in Sources */,
0E011F7D2196D97200BA59EE /* EndpointProtocol.swift in Sources */,
0E0C2125212ED29D008AB282 /* SessionError.swift in Sources */,
0EE2F9F022918DA100F56F49 /* NETCPInterface.swift in Sources */,
0E0C2125212ED29D008AB282 /* OpenVPNError.swift in Sources */,
0E12B2A821456C0200B4BAE9 /* ControlChannel.swift in Sources */,
0EFEB4552006D3C800F81029 /* SessionProxy+EncryptionBridge.swift in Sources */,
0EFEB4552006D3C800F81029 /* EncryptionBridge.swift in Sources */,
0EFEB45C2006D3C800F81029 /* ZeroingData.m in Sources */,
0EE2F9712291638600F56F49 /* IPv6Settings.swift in Sources */,
0EE2F97A2291817300F56F49 /* Errors.swift in Sources */,
0EFEB4632006D3C800F81029 /* ProtocolMacros.swift in Sources */,
0EFB902B22788512006405E4 /* RoutingTable.m in Sources */,
0EFEB46D2006D3C800F81029 /* Data+Manipulation.swift in Sources */,
0EB03E2A2290D22A006D03A0 /* NWUDPSessionState+Description.swift in Sources */,
0EE2F9F422918DA100F56F49 /* NWTCPConnectionState+Description.swift in Sources */,
0ECE3528212EB7770040F253 /* CryptoContainer.swift in Sources */,
0EFEB4742006D3C800F81029 /* CoreConfiguration.swift in Sources */,
0E07595F20EF6D1400F38FD8 /* CryptoCBC.m in Sources */,
0EFEB46F2006D3C800F81029 /* IOInterface.swift in Sources */,
0E07598020F0060E00F38FD8 /* CryptoAEAD.m in Sources */,
0E011F882196E2AB00BA59EE /* ConfigurationParser.swift in Sources */,
0EE2FA0222918DA100F56F49 /* GenericSocket.swift in Sources */,
0EE2FA0822918DA100F56F49 /* TunnelKitProvider+Interaction.swift in Sources */,
0EE2FA0422918DA100F56F49 /* TunnelKitProvider.swift in Sources */,
0EE2F9FA22918DA100F56F49 /* DNSResolver.swift in Sources */,
0EE2F9F622918DA100F56F49 /* NEUDPInterface.swift in Sources */,
0E39BCEA214B2AB60035E9DE /* ControlPacket.m in Sources */,
0EB03E3A2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift in Sources */,
0EE2F96E2291636B00F56F49 /* IPv4Settings.swift in Sources */,
0E12B2AB2145E01700B4BAE9 /* ControlChannelSerializer.swift in Sources */,
0EFEB4662006D3C800F81029 /* ZeroingData.swift in Sources */,
0EFEB4682006D3C800F81029 /* MSS.m in Sources */,
0EE2FA0622918DA100F56F49 /* Utils.swift in Sources */,
0E48AC662271ADA9009B1A98 /* PacketStream.m in Sources */,
0EB03E382290D22A006D03A0 /* Utils.swift in Sources */,
0EE2F97722916A5D00F56F49 /* OpenVPN.swift in Sources */,
0E411B9D2271F90700E0852C /* DNS.m in Sources */,
0EFEB45B2006D3C800F81029 /* TLSBox.m in Sources */,
0E58BF3922405410006FB157 /* minilzo.c in Sources */,
0EB03E362290D22A006D03A0 /* TunnelKitProvider.swift in Sources */,
0EB03E2E2290D22A006D03A0 /* TunnelKitProvider+Configuration.swift in Sources */,
0EE2F9FC22918DA100F56F49 /* TunnelKitProvider+Configuration.swift in Sources */,
0EFEB4702006D3C800F81029 /* Allocation.m in Sources */,
0E041D092152E6FE0025FE3C /* SessionProxy+TLSWrap.swift in Sources */,
0EFEB4672006D3C800F81029 /* SessionProxy.swift in Sources */,
0EB03E3C2290D22A006D03A0 /* InterfaceObserver.swift in Sources */,
0ED9C8642138139000621BA3 /* SessionProxy+CompressionFraming.swift in Sources */,
0EB03E262290D22A006D03A0 /* NWTCPConnectionState+Description.swift in Sources */,
0E041D092152E6FE0025FE3C /* TLSWrap.swift in Sources */,
0EFEB4672006D3C800F81029 /* OpenVPNSession.swift in Sources */,
0ED9C8642138139000621BA3 /* CompressionFraming.swift in Sources */,
0EFEB4722006D3C800F81029 /* ReplayProtector.m in Sources */,
0E3E0F212108A8CC00B371C1 /* SessionProxy+SessionReply.swift in Sources */,
0E3E0F212108A8CC00B371C1 /* PushReply.swift in Sources */,
0EE2FA0A22918DA100F56F49 /* InterfaceObserver.swift in Sources */,
0ECC60D82254981A0020BEAC /* ConfigurationError.swift in Sources */,
0EFEB4752006D3C800F81029 /* Errors.m in Sources */,
0E58BF532240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift in Sources */,
0E58BF532240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */,
0EB03E3F2290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */,
0EB03E342290D22A006D03A0 /* GenericSocket.swift in Sources */,
0EB03E302290D22A006D03A0 /* Keychain.swift in Sources */,
0E12B2A521454F7F00B4BAE9 /* BidirectionalState.swift in Sources */,
0EB03E242290D22A006D03A0 /* NETunnelInterface.swift in Sources */,
0EFEB4762006D3C800F81029 /* DataPath.m in Sources */,
0E0C2127212ED29D008AB282 /* SessionProxy+Configuration.swift in Sources */,
0E0C2127212ED29D008AB282 /* Configuration.swift in Sources */,
0EE2F9EE22918DA100F56F49 /* ConnectionStrategy.swift in Sources */,
0EFEB4692006D3C800F81029 /* Packet.swift in Sources */,
0E011F7A2196D93600BA59EE /* SocketType.swift in Sources */,
0EFEB45A2006D3C800F81029 /* TunnelInterface.swift in Sources */,
0EE2FA0022918DA100F56F49 /* MemoryDestination.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1333,75 +1348,78 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0EB03E212290D22A006D03A0 /* ConnectionStrategy.swift in Sources */,
0EB03E332290D22A006D03A0 /* MemoryDestination.swift in Sources */,
0E58BF4D22405C2F006FB157 /* StandardLZO.m in Sources */,
0EB03E232290D22A006D03A0 /* NETCPInterface.swift in Sources */,
0EE2F975229163C900F56F49 /* Proxy.swift in Sources */,
0EFEB4A12006D7F300F81029 /* LinkInterface.swift in Sources */,
0EE7A79920F6296F00B42E6A /* PacketMacros.m in Sources */,
0EE2F9F322918DA100F56F49 /* NETunnelInterface.swift in Sources */,
0EE2F9FF22918DA100F56F49 /* Keychain.swift in Sources */,
0E0B20432278A85C007A3CB9 /* RoutingTableEntry.m in Sources */,
0EB03E292290D22A006D03A0 /* NEUDPInterface.swift in Sources */,
0EB03E2D2290D22A006D03A0 /* DNSResolver.swift in Sources */,
0E58BF5A22411FEF006FB157 /* LZO.m in Sources */,
0E12B29F21449ADB00B4BAE9 /* NSRegularExpression+Shortcuts.swift in Sources */,
0EFEB4A02006D7F300F81029 /* ReplayProtector.m in Sources */,
0E749F602178885500BB2701 /* SessionProxy+PIA.swift in Sources */,
0EFEB4992006D7F300F81029 /* SessionProxy.swift in Sources */,
0E749F602178885500BB2701 /* OpenVPNSession+PIA.swift in Sources */,
0EE2F9F922918DA100F56F49 /* NWUDPSessionState+Description.swift in Sources */,
0EFEB4992006D7F300F81029 /* OpenVPNSession.swift in Sources */,
0EE3B3E521471C3A0027AB17 /* StaticKey.swift in Sources */,
0EE2F9AD2291853D00F56F49 /* Session.swift in Sources */,
0EFEB4962006D7F300F81029 /* ProtocolMacros.swift in Sources */,
0E3B15CA2152B05E00984B17 /* CryptoCTR.m in Sources */,
0E011F7E2196D97200BA59EE /* EndpointProtocol.swift in Sources */,
0E0C2126212ED29D008AB282 /* SessionError.swift in Sources */,
0E0C2126212ED29D008AB282 /* OpenVPNError.swift in Sources */,
0EE2F9F122918DA100F56F49 /* NETCPInterface.swift in Sources */,
0E12B2A921456C0200B4BAE9 /* ControlChannel.swift in Sources */,
0EFEB4982006D7F300F81029 /* ZeroingData.swift in Sources */,
0EFEB4A32006D7F300F81029 /* Errors.m in Sources */,
0EFEB4A22006D7F300F81029 /* CoreConfiguration.swift in Sources */,
0EE2F9722291638600F56F49 /* IPv6Settings.swift in Sources */,
0EE2F97B2291817300F56F49 /* Errors.swift in Sources */,
0EFB902C22788512006405E4 /* RoutingTable.m in Sources */,
0EFEB4952006D7F300F81029 /* SecureRandom.swift in Sources */,
0EFEB49A2006D7F300F81029 /* MSS.m in Sources */,
0EB03E2B2290D22A006D03A0 /* NWUDPSessionState+Description.swift in Sources */,
0EE2F9F522918DA100F56F49 /* NWTCPConnectionState+Description.swift in Sources */,
0ECE352A212EB88E0040F253 /* CryptoContainer.swift in Sources */,
0EFEB48D2006D7F300F81029 /* SessionProxy+EncryptionBridge.swift in Sources */,
0EFEB48D2006D7F300F81029 /* EncryptionBridge.swift in Sources */,
0EFEB4922006D7F300F81029 /* ZeroingData.m in Sources */,
0E07596020EF6D1400F38FD8 /* CryptoCBC.m in Sources */,
0EFEB4932006D7F300F81029 /* CryptoBox.m in Sources */,
0E011F892196E2AB00BA59EE /* ConfigurationParser.swift in Sources */,
0EE2FA0322918DA100F56F49 /* GenericSocket.swift in Sources */,
0EE2FA0922918DA100F56F49 /* TunnelKitProvider+Interaction.swift in Sources */,
0EE2FA0522918DA100F56F49 /* TunnelKitProvider.swift in Sources */,
0EE2F9FB22918DA100F56F49 /* DNSResolver.swift in Sources */,
0EE2F9F722918DA100F56F49 /* NEUDPInterface.swift in Sources */,
0E39BCEB214B2AB60035E9DE /* ControlPacket.m in Sources */,
0EB03E3B2290D22A006D03A0 /* TunnelKitProvider+Interaction.swift in Sources */,
0EE2F96F2291636B00F56F49 /* IPv4Settings.swift in Sources */,
0E12B2AC2145E01700B4BAE9 /* ControlChannelSerializer.swift in Sources */,
0E07598120F0060E00F38FD8 /* CryptoAEAD.m in Sources */,
0EFEB49C2006D7F300F81029 /* Data+Manipulation.swift in Sources */,
0EE2FA0722918DA100F56F49 /* Utils.swift in Sources */,
0E48AC672271ADA9009B1A98 /* PacketStream.m in Sources */,
0EB03E392290D22A006D03A0 /* Utils.swift in Sources */,
0EE2F97822916A5D00F56F49 /* OpenVPN.swift in Sources */,
0E411B9E2271F90700E0852C /* DNS.m in Sources */,
0EFEB4902006D7F300F81029 /* TunnelInterface.swift in Sources */,
0EFEB49E2006D7F300F81029 /* Allocation.m in Sources */,
0EB03E372290D22A006D03A0 /* TunnelKitProvider.swift in Sources */,
0EB03E2F2290D22A006D03A0 /* TunnelKitProvider+Configuration.swift in Sources */,
0EE2F9FD22918DA100F56F49 /* TunnelKitProvider+Configuration.swift in Sources */,
0E58BF3A22405410006FB157 /* minilzo.c in Sources */,
0E041D0A2152E6FE0025FE3C /* SessionProxy+TLSWrap.swift in Sources */,
0EFEB48E2006D7F300F81029 /* SessionProxy+SessionKey.swift in Sources */,
0EB03E3D2290D22A006D03A0 /* InterfaceObserver.swift in Sources */,
0ED9C8652138139000621BA3 /* SessionProxy+CompressionFraming.swift in Sources */,
0EB03E272290D22A006D03A0 /* NWTCPConnectionState+Description.swift in Sources */,
0E041D0A2152E6FE0025FE3C /* TLSWrap.swift in Sources */,
0EFEB48E2006D7F300F81029 /* SessionKey.swift in Sources */,
0ED9C8652138139000621BA3 /* CompressionFraming.swift in Sources */,
0EFEB4A42006D7F300F81029 /* DataPath.m in Sources */,
0ECC60D92254981A0020BEAC /* ConfigurationError.swift in Sources */,
0E3E0F222108A8CC00B371C1 /* SessionProxy+SessionReply.swift in Sources */,
0E58BF542240FAA6006FB157 /* SessionProxy+CompressionAlgorithm.swift in Sources */,
0EE2FA0B22918DA100F56F49 /* InterfaceObserver.swift in Sources */,
0E3E0F222108A8CC00B371C1 /* PushReply.swift in Sources */,
0E58BF542240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */,
0E12B2A621454F7F00B4BAE9 /* BidirectionalState.swift in Sources */,
0EB03E402290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */,
0EB03E352290D22A006D03A0 /* GenericSocket.swift in Sources */,
0EB03E312290D22A006D03A0 /* Keychain.swift in Sources */,
0EFEB4912006D7F300F81029 /* TLSBox.m in Sources */,
0EB03E252290D22A006D03A0 /* NETunnelInterface.swift in Sources */,
0EFEB49D2006D7F300F81029 /* IOInterface.swift in Sources */,
0E0C2128212ED29D008AB282 /* SessionProxy+Configuration.swift in Sources */,
0EFEB4972006D7F300F81029 /* SessionProxy+Authenticator.swift in Sources */,
0E0C2128212ED29D008AB282 /* Configuration.swift in Sources */,
0EE2F9EF22918DA100F56F49 /* ConnectionStrategy.swift in Sources */,
0EFEB4972006D7F300F81029 /* Authenticator.swift in Sources */,
0E011F7B2196D93600BA59EE /* SocketType.swift in Sources */,
0EFEB49B2006D7F300F81029 /* Packet.swift in Sources */,
0EE2FA0122918DA100F56F49 /* MemoryDestination.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1409,24 +1427,24 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0EA82A3A2190B2B9007960EB /* RandomTests.swift in Sources */,
0E011F822196E23800BA59EE /* ConfigurationParserTests.swift in Sources */,
0EA82A332190B2B9007960EB /* DataPathPerformanceTests.swift in Sources */,
0EA82A372190B2B9007960EB /* LinkTests.swift in Sources */,
0EA82A352190B2B9007960EB /* EncryptionPerformanceTests.swift in Sources */,
0EA82A2F2190B2B9007960EB /* AppExtensionTests.swift in Sources */,
0EA82A322190B2B9007960EB /* DataPathEncryptionTests.swift in Sources */,
0EA82A392190B2B9007960EB /* PushTests.swift in Sources */,
0EA82A3C2190B2B9007960EB /* StaticKeyTests.swift in Sources */,
0EA82A302190B2B9007960EB /* ControlChannelTests.swift in Sources */,
0EA82A312190B2B9007960EB /* DataManipulationTests.swift in Sources */,
0EA82A382190B2B9007960EB /* PacketTests.swift in Sources */,
0E0B203D227886AD007A3CB9 /* RoutingTests.swift in Sources */,
0EA82A3B2190B2B9007960EB /* RawPerformanceTests.swift in Sources */,
0EA82A362190B2B9007960EB /* EncryptionTests.swift in Sources */,
0EA82A3D2190B2B9007960EB /* TestUtils.swift in Sources */,
0EA82A342190B2B9007960EB /* DNSTests.swift in Sources */,
0E58BF3D2240547F006FB157 /* CompressionTests.swift in Sources */,
0EE2FA642291954400F56F49 /* StaticKeyTests.swift in Sources */,
0EE2FA552291954400F56F49 /* CompressionTests.swift in Sources */,
0EE2FA5B2291954400F56F49 /* DNSTests.swift in Sources */,
0EE2FA592291954400F56F49 /* DataPathEncryptionTests.swift in Sources */,
0EE2FA622291954400F56F49 /* RawPerformanceTests.swift in Sources */,
0EE2FA5F2291954400F56F49 /* PacketTests.swift in Sources */,
0EE2FA572291954400F56F49 /* ControlChannelTests.swift in Sources */,
0EE2FA602291954400F56F49 /* PushTests.swift in Sources */,
0EE2FA542291954400F56F49 /* AppExtensionTests.swift in Sources */,
0EE2FA632291954400F56F49 /* RoutingTests.swift in Sources */,
0EE2FA5C2291954400F56F49 /* EncryptionPerformanceTests.swift in Sources */,
0EE2FA612291954400F56F49 /* RandomTests.swift in Sources */,
0EE2FA5D2291954400F56F49 /* EncryptionTests.swift in Sources */,
0EE2FA652291954400F56F49 /* TestUtils.swift in Sources */,
0EE2FA582291954400F56F49 /* DataManipulationTests.swift in Sources */,
0EE2FA5E2291954400F56F49 /* LinkTests.swift in Sources */,
0EE2FA562291954400F56F49 /* ConfigurationParserTests.swift in Sources */,
0EE2FA5A2291954400F56F49 /* DataPathPerformanceTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -53,7 +53,7 @@ extension TunnelKitProvider {
resolvedAddresses: nil,
endpointProtocols: nil,
mtu: 1250,
sessionConfiguration: SessionProxy.ConfigurationBuilder().build(),
sessionConfiguration: OpenVPN.ConfigurationBuilder().build(),
shouldDebug: false,
debugLogFormat: nil,
masksPrivateData: true
@ -71,7 +71,7 @@ extension TunnelKitProvider {
public var mtu: Int
/// The session configuration.
public var sessionConfiguration: SessionProxy.Configuration
public var sessionConfiguration: OpenVPN.Configuration
// MARK: Debugging
@ -91,7 +91,7 @@ extension TunnelKitProvider {
- Parameter ca: The CA certificate.
*/
public init(sessionConfiguration: SessionProxy.Configuration) {
public init(sessionConfiguration: OpenVPN.Configuration) {
prefersResolvedAddresses = ConfigurationBuilder.defaults.prefersResolvedAddresses
resolvedAddresses = nil
mtu = ConfigurationBuilder.defaults.mtu
@ -114,34 +114,34 @@ extension TunnelKitProvider {
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.ca)]")
}
var sessionConfigurationBuilder = SessionProxy.ConfigurationBuilder()
var sessionConfigurationBuilder = OpenVPN.ConfigurationBuilder()
if let cipherAlgorithm = providerConfiguration[S.cipherAlgorithm] as? String {
sessionConfigurationBuilder.cipher = SessionProxy.Cipher(rawValue: cipherAlgorithm)
sessionConfigurationBuilder.cipher = OpenVPN.Cipher(rawValue: cipherAlgorithm)
}
if let digestAlgorithm = providerConfiguration[S.digestAlgorithm] as? String {
sessionConfigurationBuilder.digest = SessionProxy.Digest(rawValue: digestAlgorithm)
sessionConfigurationBuilder.digest = OpenVPN.Digest(rawValue: digestAlgorithm)
}
if let compressionFramingValue = providerConfiguration[S.compressionFraming] as? Int, let compressionFraming = SessionProxy.CompressionFraming(rawValue: compressionFramingValue) {
if let compressionFramingValue = providerConfiguration[S.compressionFraming] as? Int, let compressionFraming = OpenVPN.CompressionFraming(rawValue: compressionFramingValue) {
sessionConfigurationBuilder.compressionFraming = compressionFraming
} else {
sessionConfigurationBuilder.compressionFraming = ConfigurationBuilder.defaults.sessionConfiguration.compressionFraming
}
if let compressionAlgorithmValue = providerConfiguration[S.compressionAlgorithm] as? Int, let compressionAlgorithm = SessionProxy.CompressionAlgorithm(rawValue: compressionAlgorithmValue) {
if let compressionAlgorithmValue = providerConfiguration[S.compressionAlgorithm] as? Int, let compressionAlgorithm = OpenVPN.CompressionAlgorithm(rawValue: compressionAlgorithmValue) {
sessionConfigurationBuilder.compressionAlgorithm = compressionAlgorithm
} else {
sessionConfigurationBuilder.compressionAlgorithm = ConfigurationBuilder.defaults.sessionConfiguration.compressionAlgorithm
}
sessionConfigurationBuilder.ca = CryptoContainer(pem: caPEM)
sessionConfigurationBuilder.ca = OpenVPN.CryptoContainer(pem: caPEM)
if let clientPEM = providerConfiguration[S.clientCertificate] as? String {
guard let keyPEM = providerConfiguration[S.clientKey] as? String else {
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.clientKey)]")
}
sessionConfigurationBuilder.clientCertificate = CryptoContainer(pem: clientPEM)
sessionConfigurationBuilder.clientKey = CryptoContainer(pem: keyPEM)
sessionConfigurationBuilder.clientCertificate = OpenVPN.CryptoContainer(pem: clientPEM)
sessionConfigurationBuilder.clientKey = OpenVPN.CryptoContainer(pem: keyPEM)
}
if let tlsWrapData = providerConfiguration[S.tlsWrap] as? Data {
do {
sessionConfigurationBuilder.tlsWrap = try SessionProxy.TLSWrap.deserialized(tlsWrapData)
sessionConfigurationBuilder.tlsWrap = try OpenVPN.TLSWrap.deserialized(tlsWrapData)
} catch {
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.tlsWrap)]")
}
@ -178,7 +178,7 @@ extension TunnelKitProvider {
sessionConfigurationBuilder.proxyBypassDomains = providerConfiguration[S.proxyBypassDomains] as? [String]
if let routingPoliciesStrings = providerConfiguration[S.routingPolicies] as? [String] {
sessionConfigurationBuilder.routingPolicies = try routingPoliciesStrings.map {
guard let policy = SessionProxy.RoutingPolicy(rawValue: $0) else {
guard let policy = OpenVPN.RoutingPolicy(rawValue: $0) else {
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.routingPolicies)] has a badly formed element")
}
return policy
@ -286,7 +286,7 @@ extension TunnelKitProvider {
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.resolvedAddresses`
public let resolvedAddresses: [String]?
/// - Seealso: `SessionProxy.Configuration.endpointProtocols`
/// - Seealso: `OpenVPN.Configuration.endpointProtocols`
@available(*, deprecated)
public var endpointProtocols: [EndpointProtocol]?
@ -294,7 +294,7 @@ extension TunnelKitProvider {
public let mtu: Int
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.sessionConfiguration`
public let sessionConfiguration: SessionProxy.Configuration
public let sessionConfiguration: OpenVPN.Configuration
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.shouldDebug`
public let shouldDebug: Bool
@ -511,7 +511,7 @@ extension TunnelKitProvider {
- Returns: The generated `NETunnelProviderProtocol` object.
- Throws: `ProviderError.credentials` if unable to store `credentials.password` to the `appGroup` keychain.
*/
public func generatedTunnelProtocol(withBundleIdentifier bundleIdentifier: String, appGroup: String, credentials: SessionProxy.Credentials? = nil) throws -> NETunnelProviderProtocol {
public func generatedTunnelProtocol(withBundleIdentifier bundleIdentifier: String, appGroup: String, credentials: OpenVPN.Credentials? = nil) throws -> NETunnelProviderProtocol {
let protocolConfiguration = NETunnelProviderProtocol()
protocolConfiguration.providerBundleIdentifier = bundleIdentifier

View File

@ -115,7 +115,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
// MARK: Internal state
private var proxy: SessionProxy?
private var session: OpenVPNSession?
private var socket: GenericSocket?
@ -169,10 +169,11 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
}
// optional credentials
let credentials: SessionProxy.Credentials?
let credentials: OpenVPN.Credentials?
if let username = protocolConfiguration.username, let passwordReference = protocolConfiguration.passwordReference,
let password = try? Keychain.password(for: username, reference: passwordReference) {
credentials = SessionProxy.Credentials(username, password)
credentials = OpenVPN.Credentials(username, password)
} else {
credentials = nil
}
@ -204,24 +205,24 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
log.info("Starting tunnel...")
cfg.clearLastError(in: appGroup)
guard SessionProxy.EncryptionBridge.prepareRandomNumberGenerator(seedLength: prngSeedLength) else {
guard OpenVPN.prepareRandomNumberGenerator(seedLength: prngSeedLength) else {
completionHandler(ProviderConfigurationError.prngInitialization)
return
}
cfg.print(appVersion: appVersion)
let proxy: SessionProxy
let session: OpenVPNSession
do {
proxy = try SessionProxy(queue: tunnelQueue, configuration: cfg.sessionConfiguration, cachesURL: cachesURL)
session = try OpenVPNSession(queue: tunnelQueue, configuration: cfg.sessionConfiguration, cachesURL: cachesURL)
refreshDataCount()
} catch let e {
completionHandler(e)
return
}
proxy.credentials = credentials
proxy.delegate = self
self.proxy = proxy
session.credentials = credentials
session.delegate = self
self.session = session
logCurrentSSID()
@ -237,7 +238,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
log.info("Stopping tunnel...")
cfg.clearLastError(in: appGroup)
guard let proxy = proxy else {
guard let session = session else {
flushLog()
completionHandler()
return
@ -256,7 +257,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
pendingHandler()
}
tunnelQueue.sync {
proxy.shutdown(error: nil)
session.shutdown(error: nil)
}
}
@ -268,7 +269,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
response = memoryLog.description.data(using: .utf8)
case .dataCount:
if let proxy = proxy, let dataCount = proxy.dataCount() {
if let session = session, let dataCount = session.dataCount() {
response = Data()
response?.append(UInt64(dataCount.0)) // inbound
response?.append(UInt64(dataCount.1)) // outbound
@ -312,8 +313,8 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
}
private func finishTunnelDisconnection(error: Error?) {
if let proxy = proxy, !(reasserting && proxy.canRebindLink()) {
proxy.cleanup()
if let session = session, !(reasserting && session.canRebindLink()) {
session.cleanup()
}
socket?.delegate = nil
@ -346,7 +347,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
// provided, so we do this with optional fallback to .socketActivity
//
// socketActivity makes sense, given that any other error would normally come
// from SessionProxy.stopError. other paths to disposeTunnel() are only coming
// from OpenVPN.stopError. other paths to disposeTunnel() are only coming
// from stopTunnel(), in which case we don't need to feed an error parameter to
// the stop completion handler
//
@ -373,7 +374,7 @@ open class TunnelKitProvider: NEPacketTunnelProvider {
tunnelQueue.schedule(after: .milliseconds(dataCountInterval)) { [weak self] in
self?.refreshDataCount()
}
guard isCountingData, let proxy = proxy, let dataCount = proxy.dataCount() else {
guard isCountingData, let session = session, let dataCount = session.dataCount() else {
defaults?.removeDataCountArray()
return
}
@ -400,19 +401,19 @@ extension TunnelKitProvider: GenericSocketDelegate {
}
func socketDidBecomeActive(_ socket: GenericSocket) {
guard let proxy = proxy else {
guard let session = session else {
return
}
if proxy.canRebindLink() {
proxy.rebindLink(socket.link(withMTU: cfg.mtu))
if session.canRebindLink() {
session.rebindLink(socket.link(withMTU: cfg.mtu))
reasserting = false
} else {
proxy.setLink(socket.link(withMTU: cfg.mtu))
session.setLink(socket.link(withMTU: cfg.mtu))
}
}
func socket(_ socket: GenericSocket, didShutdownWithFailure failure: Bool) {
guard let proxy = proxy else {
guard let session = session else {
return
}
@ -421,14 +422,14 @@ extension TunnelKitProvider: GenericSocketDelegate {
var upgradedSocket: GenericSocket?
// look for error causing shutdown
shutdownError = proxy.stopError
shutdownError = session.stopError
if failure && (shutdownError == nil) {
shutdownError = ProviderError.linkError
}
didTimeoutNegotiation = (shutdownError as? SessionError == .negotiationTimeout)
didTimeoutNegotiation = (shutdownError as? OpenVPNError == .negotiationTimeout)
// only try upgrade on network errors
if shutdownError as? SessionError == nil {
if shutdownError as? OpenVPNError == nil {
upgradedSocket = socket.upgraded()
}
@ -465,54 +466,54 @@ extension TunnelKitProvider: GenericSocketDelegate {
func socketHasBetterPath(_ socket: GenericSocket) {
log.debug("Stopping tunnel due to a new better path")
logCurrentSSID()
proxy?.reconnect(error: ProviderError.networkChanged)
session?.reconnect(error: ProviderError.networkChanged)
}
}
extension TunnelKitProvider: SessionProxyDelegate {
extension TunnelKitProvider: OpenVPNSessionDelegate {
// MARK: SessionProxyDelegate (tunnel queue)
// MARK: OpenVPNSessionDelegate (tunnel queue)
/// :nodoc:
public func sessionDidStart(_ proxy: SessionProxy, remoteAddress: String, reply: SessionReply) {
public func sessionDidStart(_ session: OpenVPNSession, remoteAddress: String, options: OpenVPN.Configuration) {
reasserting = false
log.info("Session did start")
log.info("Returned ifconfig parameters:")
log.info("\tRemote: \(remoteAddress.maskedDescription)")
log.info("\tIPv4: \(reply.options.ipv4?.description ?? "not configured")")
log.info("\tIPv6: \(reply.options.ipv6?.description ?? "not configured")")
if let routingPolicies = reply.options.routingPolicies {
log.info("\tIPv4: \(options.ipv4?.description ?? "not configured")")
log.info("\tIPv6: \(options.ipv6?.description ?? "not configured")")
if let routingPolicies = options.routingPolicies {
log.info("\tGateway: \(routingPolicies.map { $0.rawValue })")
} else {
log.info("\tGateway: not configured")
}
if let dnsServers = reply.options.dnsServers, !dnsServers.isEmpty {
if let dnsServers = options.dnsServers, !dnsServers.isEmpty {
log.info("\tDNS: \(dnsServers.map { $0.maskedDescription })")
} else {
log.info("\tDNS: not configured")
}
if let searchDomain = reply.options.searchDomain, !searchDomain.isEmpty {
if let searchDomain = options.searchDomain, !searchDomain.isEmpty {
log.info("\tDomain: \(searchDomain.maskedDescription)")
} else {
log.info("\tDomain: not configured")
}
if reply.options.httpProxy != nil || reply.options.httpsProxy != nil {
if options.httpProxy != nil || options.httpsProxy != nil {
log.info("\tProxy:")
if let proxy = reply.options.httpProxy {
if let proxy = options.httpProxy {
log.info("\t\tHTTP: \(proxy.maskedDescription)")
}
if let proxy = reply.options.httpsProxy {
if let proxy = options.httpsProxy {
log.info("\t\tHTTPS: \(proxy.maskedDescription)")
}
if let bypass = reply.options.proxyBypassDomains {
if let bypass = options.proxyBypassDomains {
log.info("\t\tBypass domains: \(bypass.maskedDescription)")
}
}
bringNetworkUp(remoteAddress: remoteAddress, configuration: proxy.configuration, reply: reply) { (error) in
bringNetworkUp(remoteAddress: remoteAddress, localOptions: session.configuration, options: options) { (error) in
if let error = error {
log.error("Failed to configure tunnel: \(error)")
self.pendingStartHandler?(error)
@ -522,7 +523,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
log.info("Tunnel interface is now UP")
proxy.setTunnel(tunnel: NETunnelInterface(impl: self.packetFlow, isIPv6: reply.options.ipv6 != nil))
session.setTunnel(tunnel: NETunnelInterface(impl: self.packetFlow, isIPv6: options.ipv6 != nil))
self.pendingStartHandler?(nil)
self.pendingStartHandler = nil
@ -533,7 +534,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
}
/// :nodoc:
public func sessionDidStop(_: SessionProxy, shouldReconnect: Bool) {
public func sessionDidStop(_: OpenVPNSession, shouldReconnect: Bool) {
log.info("Session did stop")
isCountingData = false
@ -543,14 +544,14 @@ extension TunnelKitProvider: SessionProxyDelegate {
socket?.shutdown()
}
private func bringNetworkUp(remoteAddress: String, configuration: SessionProxy.Configuration, reply: SessionReply, completionHandler: @escaping (Error?) -> Void) {
let routingPolicies = configuration.routingPolicies ?? reply.options.routingPolicies
private func bringNetworkUp(remoteAddress: String, localOptions: OpenVPN.Configuration, options: OpenVPN.Configuration, completionHandler: @escaping (Error?) -> Void) {
let routingPolicies = localOptions.routingPolicies ?? options.routingPolicies
let isIPv4Gateway = routingPolicies?.contains(.IPv4) ?? false
let isIPv6Gateway = routingPolicies?.contains(.IPv6) ?? false
let isGateway = isIPv4Gateway || isIPv6Gateway
var ipv4Settings: NEIPv4Settings?
if let ipv4 = reply.options.ipv4 {
if let ipv4 = options.ipv4 {
var routes: [NEIPv4Route] = []
// route all traffic to VPN?
@ -579,7 +580,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
}
var ipv6Settings: NEIPv6Settings?
if let ipv6 = reply.options.ipv6 {
if let ipv6 = options.ipv6 {
var routes: [NEIPv6Route] = []
// route all traffic to VPN?
@ -616,11 +617,11 @@ extension TunnelKitProvider: SessionProxyDelegate {
hasGateway = true
}
guard !isGateway || hasGateway else {
proxy?.shutdown(error: ProviderError.gatewayUnattainable)
session?.shutdown(error: ProviderError.gatewayUnattainable)
return
}
var dnsServers = cfg.sessionConfiguration.dnsServers ?? reply.options.dnsServers ?? []
var dnsServers = cfg.sessionConfiguration.dnsServers ?? options.dnsServers ?? []
// fall back
if dnsServers.isEmpty {
@ -632,7 +633,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
if !isGateway {
dnsSettings.matchDomains = [""]
}
if let searchDomain = cfg.sessionConfiguration.searchDomain ?? reply.options.searchDomain {
if let searchDomain = cfg.sessionConfiguration.searchDomain ?? options.searchDomain {
dnsSettings.domainName = searchDomain
dnsSettings.searchDomains = [searchDomain]
if !isGateway {
@ -652,13 +653,13 @@ extension TunnelKitProvider: SessionProxyDelegate {
}
var proxySettings: NEProxySettings?
if let httpsProxy = cfg.sessionConfiguration.httpsProxy ?? reply.options.httpsProxy {
if let httpsProxy = cfg.sessionConfiguration.httpsProxy ?? options.httpsProxy {
proxySettings = NEProxySettings()
proxySettings?.httpsServer = httpsProxy.neProxy()
proxySettings?.httpsEnabled = true
log.info("Routing: Setting HTTPS proxy \(httpsProxy.address.maskedDescription):\(httpsProxy.port)")
}
if let httpProxy = cfg.sessionConfiguration.httpProxy ?? reply.options.httpProxy {
if let httpProxy = cfg.sessionConfiguration.httpProxy ?? options.httpProxy {
if proxySettings == nil {
proxySettings = NEProxySettings()
}
@ -668,7 +669,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
}
// only set if there is a proxy (proxySettings set to non-nil above)
if let bypass = cfg.sessionConfiguration.proxyBypassDomains ?? reply.options.proxyBypassDomains {
if let bypass = cfg.sessionConfiguration.proxyBypassDomains ?? options.proxyBypassDomains {
proxySettings?.exceptionList = bypass
log.info("Routing: Setting proxy by-pass list: \(bypass.maskedDescription)")
}
@ -689,7 +690,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
log.info("Block local: Suppressing IPv4 route \(destination)/\($0.prefix())")
let included = NEIPv4Route(destinationAddress: destination, subnetMask: netmask)
included.gatewayAddress = reply.options.ipv4?.defaultGateway
included.gatewayAddress = options.ipv4?.defaultGateway
ipv4Settings?.includedRoutes?.append(included)
}
}
@ -704,7 +705,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
log.info("Block local: Suppressing IPv6 route \(destination)/\($0.prefix())")
let included = NEIPv6Route(destinationAddress: destination, networkPrefixLength: prefix as NSNumber)
included.gatewayAddress = reply.options.ipv6?.defaultGateway
included.gatewayAddress = options.ipv6?.defaultGateway
ipv6Settings?.includedRoutes?.append(included)
}
}
@ -806,7 +807,7 @@ extension TunnelKitProvider {
default:
break
}
} else if let se = error as? SessionError {
} else if let se = error as? OpenVPNError {
switch se {
case .negotiationTimeout, .pingTimeout, .staleSession:
return .timeout

View File

@ -0,0 +1,42 @@
//
// Errors.swift
// TunnelKit
//
// Created by Davide De Rosa on 05/19/19.
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// 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/>.
//
import Foundation
import __TunnelKitCore
extension Error {
func isTunnelKitError() -> Bool {
let te = self as NSError
return te.domain == TunnelKitErrorDomain
}
func tunnelKitErrorCode() -> TunnelKitErrorCode? {
let te = self as NSError
guard te.domain == TunnelKitErrorDomain else {
return nil
}
return TunnelKitErrorCode(rawValue: te.code)
}
}

View File

@ -0,0 +1,92 @@
//
// Session.swift
// TunnelKit
//
// Created by Davide De Rosa on 05/19/19.
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// 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/>.
//
import Foundation
/// Defines the basics of a VPN session.
public protocol Session {
/**
Establishes the link interface for this session. The interface must be up and running for sending and receiving packets.
- Precondition: `link` is an active network interface.
- Postcondition: The VPN negotiation is started.
- Parameter link: The `LinkInterface` on which to establish the VPN session.
*/
func setLink(_ link: LinkInterface)
/**
Returns `true` if the current session can rebind to a new link with `rebindLink(...)`.
- Returns: `true` if supports link rebinding.
*/
func canRebindLink() -> Bool
/**
Rebinds the session to a new link if supported.
- Precondition: `link` is an active network interface.
- Postcondition: The VPN session is active.
- Parameter link: The `LinkInterface` on which to establish the VPN session.
- Seealso: `canRebindLink()`.
*/
func rebindLink(_ link: LinkInterface)
/**
Establishes the tunnel interface for this session. The interface must be up and running for sending and receiving packets.
- Precondition: `tunnel` is an active network interface.
- Postcondition: The VPN data channel is open.
- Parameter tunnel: The `TunnelInterface` on which to exchange the VPN data traffic.
*/
func setTunnel(tunnel: TunnelInterface)
/**
Returns the current data bytes count.
- Returns: The current data bytes count as a pair, inbound first.
*/
func dataCount() -> (Int, Int)?
/**
Shuts down the session with an optional `Error` reason. Does nothing if the session is already stopped or about to stop.
- Parameter error: An optional `Error` being the reason of the shutdown.
*/
func shutdown(error: Error?)
/**
Shuts down the session with an optional `Error` reason and signals a reconnect flag to `OpenVPNSessionDelegate.sessionDidStop(...)`. Does nothing if the session is already stopped or about to stop.
- Parameter error: An optional `Error` being the reason of the shutdown.
- Seealso: `OpenVPNSessionDelegate.sessionDidStop(...)`
*/
func reconnect(error: Error?)
/**
Cleans up the session resources.
*/
func cleanup()
}

View File

@ -1,5 +1,5 @@
//
// SessionProxy+Authenticator.swift
// Authenticator.swift
// TunnelKit
//
// Created by Davide De Rosa on 2/9/17.
@ -48,7 +48,7 @@ fileprivate extension ZeroingData {
}
}
extension SessionProxy {
extension OpenVPN {
class Authenticator {
private var controlBuffer: ZeroingData
@ -90,7 +90,7 @@ extension SessionProxy {
// MARK: Authentication request
// Ruby: on_tls_connect
func putAuth(into: TLSBox, options: SessionProxy.Configuration) throws {
func putAuth(into: TLSBox, options: Configuration) throws {
let raw = Z(ProtocolMacros.tlsPrefix)
// local keys
@ -172,7 +172,7 @@ extension SessionProxy {
let prefix = controlBuffer.withOffset(0, count: prefixLength)
guard prefix.isEqual(to: ProtocolMacros.tlsPrefix) else {
throw SessionError.wrongControlDataPrefix
throw OpenVPNError.wrongControlDataPrefix
}
var offset = ProtocolMacros.tlsPrefix.count

View File

@ -1,5 +1,5 @@
//
// SessionProxy+CompressionAlgorithm.swift
// CompressionAlgorithm.swift
// TunnelKit
//
// Created by Davide De Rosa on 3/19/19.
@ -26,7 +26,7 @@
import Foundation
import __TunnelKitOpenVPN
extension SessionProxy {
extension OpenVPN {
/// Defines the type of compression algorithm.
public enum CompressionAlgorithm: Int, Codable, CustomStringConvertible {

View File

@ -1,5 +1,5 @@
//
// SessionProxy+CompressionFraming.swift
// CompressionFraming.swift
// TunnelKit
//
// Created by Davide De Rosa on 8/30/18.
@ -26,7 +26,7 @@
import Foundation
import __TunnelKitOpenVPN
extension SessionProxy {
extension OpenVPN {
/// Defines the type of compression framing.
public enum CompressionFraming: Int, Codable, CustomStringConvertible {

View File

@ -1,5 +1,5 @@
//
// SessionProxy+Configuration.swift
// Configuration.swift
// TunnelKit
//
// Created by Davide De Rosa on 8/23/18.
@ -36,7 +36,7 @@
import Foundation
extension SessionProxy {
extension OpenVPN {
/// A pair of credentials for authentication.
public struct Credentials: Codable, Equatable {
@ -61,7 +61,7 @@ extension SessionProxy {
}
}
/// The available encryption algorithms.
/// Encryption algorithm.
public enum Cipher: String, Codable, CustomStringConvertible {
// WARNING: must match OpenSSL algorithm names
@ -114,7 +114,7 @@ extension SessionProxy {
}
}
/// The available message digest algorithms.
/// Message digest algorithm.
public enum Digest: String, Codable, CustomStringConvertible {
// WARNING: must match OpenSSL algorithm names
@ -167,22 +167,22 @@ extension SessionProxy {
static let compressionFraming: CompressionFraming = .disabled
}
/// The way to create a `SessionProxy.Configuration` object for a `SessionProxy`.
/// The way to create a `Configuration` object for a `OpenVPNSession`.
public struct ConfigurationBuilder {
// MARK: General
/// The cipher algorithm for data encryption.
public var cipher: SessionProxy.Cipher?
public var cipher: Cipher?
/// The digest algorithm for HMAC.
public var digest: SessionProxy.Digest?
public var digest: Digest?
/// Compression framing, disabled by default.
public var compressionFraming: SessionProxy.CompressionFraming?
public var compressionFraming: CompressionFraming?
/// Compression algorithm, disabled by default.
public var compressionAlgorithm: SessionProxy.CompressionAlgorithm?
public var compressionAlgorithm: CompressionAlgorithm?
/// The CA for TLS negotiation (PEM format).
public var ca: CryptoContainer?
@ -194,7 +194,7 @@ extension SessionProxy {
public var clientKey: CryptoContainer?
/// The optional TLS wrapping.
public var tlsWrap: SessionProxy.TLSWrap?
public var tlsWrap: TLSWrap?
/// If set, overrides TLS security level (0 = lowest).
public var tlsSecurityLevel: Int?
@ -232,10 +232,10 @@ extension SessionProxy {
// MARK: Routing
/// The settings for IPv4. `SessionProxy` only evaluates this server-side.
/// The settings for IPv4. `OpenVPNSession` only evaluates this server-side.
public var ipv4: IPv4Settings?
/// The settings for IPv6. `SessionProxy` only evaluates this server-side.
/// The settings for IPv6. `OpenVPNSession` only evaluates this server-side.
public var ipv6: IPv6Settings?
/// The DNS servers.
@ -261,9 +261,9 @@ extension SessionProxy {
}
/**
Builds a `SessionProxy.Configuration` object.
Builds a `Configuration` object.
- Returns: A `SessionProxy.Configuration` object with this builder.
- Returns: A `Configuration` object with this builder.
*/
public func build() -> Configuration {
return Configuration(
@ -314,85 +314,85 @@ extension SessionProxy {
}
}
/// The immutable configuration for `SessionProxy`.
/// The immutable configuration for `OpenVPNSession`.
public struct Configuration: Codable {
/// - Seealso: `SessionProxy.ConfigurationBuilder.cipher`
/// - Seealso: `ConfigurationBuilder.cipher`
public let cipher: Cipher?
/// - Seealso: `SessionProxy.ConfigurationBuilder.digest`
/// - Seealso: `ConfigurationBuilder.digest`
public let digest: Digest?
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
/// - Seealso: `ConfigurationBuilder.compressionFraming`
public let compressionFraming: CompressionFraming?
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
/// - Seealso: `ConfigurationBuilder.compressionAlgorithm`
public let compressionAlgorithm: CompressionAlgorithm?
/// - Seealso: `SessionProxy.ConfigurationBuilder.ca`
/// - Seealso: `ConfigurationBuilder.ca`
public let ca: CryptoContainer?
/// - Seealso: `SessionProxy.ConfigurationBuilder.clientCertificate`
/// - Seealso: `ConfigurationBuilder.clientCertificate`
public let clientCertificate: CryptoContainer?
/// - Seealso: `SessionProxy.ConfigurationBuilder.clientKey`
/// - Seealso: `ConfigurationBuilder.clientKey`
public let clientKey: CryptoContainer?
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
/// - Seealso: `ConfigurationBuilder.tlsWrap`
public let tlsWrap: TLSWrap?
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsSecurityLevel`
/// - Seealso: `ConfigurationBuilder.tlsSecurityLevel`
public let tlsSecurityLevel: Int?
/// - Seealso: `SessionProxy.ConfigurationBuilder.keepAliveInterval`
/// - Seealso: `ConfigurationBuilder.keepAliveInterval`
public let keepAliveInterval: TimeInterval?
/// - Seealso: `SessionProxy.ConfigurationBuilder.renegotiatesAfter`
/// - Seealso: `ConfigurationBuilder.renegotiatesAfter`
public let renegotiatesAfter: TimeInterval?
/// - Seealso: `SessionProxy.ConfigurationBuilder.hostname`
/// - Seealso: `ConfigurationBuilder.hostname`
public let hostname: String?
/// - Seealso: `SessionProxy.ConfigurationBuilder.endpointProtocols`
/// - Seealso: `ConfigurationBuilder.endpointProtocols`
public let endpointProtocols: [EndpointProtocol]?
/// - Seealso: `SessionProxy.ConfigurationBuilder.checksEKU`
/// - Seealso: `ConfigurationBuilder.checksEKU`
public let checksEKU: Bool?
/// - Seealso: `SessionProxy.ConfigurationBuilder.randomizeEndpoint`
/// - Seealso: `ConfigurationBuilder.randomizeEndpoint`
public let randomizeEndpoint: Bool?
/// - Seealso: `SessionProxy.ConfigurationBuilder.usesPIAPatches`
/// - Seealso: `ConfigurationBuilder.usesPIAPatches`
public let usesPIAPatches: Bool?
/// - Seealso: `SessionProxy.ConfigurationBuilder.authToken`
/// - Seealso: `ConfigurationBuilder.authToken`
public let authToken: String?
/// - Seealso: `SessionProxy.ConfigurationBuilder.peerId`
/// - Seealso: `ConfigurationBuilder.peerId`
public let peerId: UInt32?
/// - Seealso: `SessionProxy.ConfigurationBuilder.ipv4`
/// - Seealso: `ConfigurationBuilder.ipv4`
public let ipv4: IPv4Settings?
/// - Seealso: `SessionProxy.ConfigurationBuilder.ipv6`
/// - Seealso: `ConfigurationBuilder.ipv6`
public let ipv6: IPv6Settings?
/// - Seealso: `SessionProxy.ConfigurationBuilder.dnsServers`
/// - Seealso: `ConfigurationBuilder.dnsServers`
public let dnsServers: [String]?
/// - Seealso: `SessionProxy.ConfigurationBuilder.searchDomain`
/// - Seealso: `ConfigurationBuilder.searchDomain`
public let searchDomain: String?
/// - Seealso: `SessionProxy.ConfigurationBuilder.httpProxy`
/// - Seealso: `ConfigurationBuilder.httpProxy`
public let httpProxy: Proxy?
/// - Seealso: `SessionProxy.ConfigurationBuilder.httpsProxy`
/// - Seealso: `ConfigurationBuilder.httpsProxy`
public let httpsProxy: Proxy?
/// - Seealso: `SessionProxy.ConfigurationBuilder.proxyBypassDomains`
/// - Seealso: `ConfigurationBuilder.proxyBypassDomains`
public let proxyBypassDomains: [String]?
/// - Seealso: `SessionProxy.ConfigurationBuilder.routingPolicies`
/// - Seealso: `ConfigurationBuilder.routingPolicies`
public let routingPolicies: [RoutingPolicy]?
// MARK: Shortcuts
@ -416,15 +416,15 @@ extension SessionProxy {
// MARK: Modification
extension SessionProxy.Configuration {
extension OpenVPN.Configuration {
/**
Returns a `SessionProxy.ConfigurationBuilder` to use this configuration as a starting point for a new one.
Returns a `ConfigurationBuilder` to use this configuration as a starting point for a new one.
- Returns: An editable `SessionProxy.ConfigurationBuilder` initialized with this configuration.
- Returns: An editable `ConfigurationBuilder` initialized with this configuration.
*/
public func builder() -> SessionProxy.ConfigurationBuilder {
var builder = SessionProxy.ConfigurationBuilder()
public func builder() -> OpenVPN.ConfigurationBuilder {
var builder = OpenVPN.ConfigurationBuilder()
builder.cipher = cipher
builder.digest = digest
builder.compressionFraming = compressionFraming

File diff suppressed because it is too large Load Diff

View File

@ -30,210 +30,212 @@ import __TunnelKitOpenVPN
private let log = SwiftyBeaver.self
class ControlChannelError: Error, CustomStringConvertible {
let description: String
init(_ message: String) {
description = "\(String(describing: ControlChannelError.self))(\(message))"
}
}
class ControlChannel {
private let serializer: ControlChannelSerializer
private(set) var sessionId: Data?
var remoteSessionId: Data? {
didSet {
if let id = remoteSessionId {
log.debug("Control: Remote sessionId is \(id.toHex())")
}
extension OpenVPN {
class ControlChannelError: Error, CustomStringConvertible {
let description: String
init(_ message: String) {
description = "\(String(describing: ControlChannelError.self))(\(message))"
}
}
private var queue: BidirectionalState<[ControlPacket]>
class ControlChannel {
private let serializer: ControlChannelSerializer
private(set) var sessionId: Data?
var remoteSessionId: Data? {
didSet {
if let id = remoteSessionId {
log.debug("Control: Remote sessionId is \(id.toHex())")
}
}
}
private var currentPacketId: BidirectionalState<UInt32>
private var queue: BidirectionalState<[ControlPacket]>
private var pendingAcks: Set<UInt32>
private var currentPacketId: BidirectionalState<UInt32>
private var plainBuffer: ZeroingData
private var pendingAcks: Set<UInt32>
private var dataCount: BidirectionalState<Int>
convenience init() {
self.init(serializer: PlainSerializer())
}
convenience init(withAuthKey key: StaticKey, digest: SessionProxy.Digest) throws {
self.init(serializer: try AuthSerializer(withKey: key, digest: digest))
}
private var plainBuffer: ZeroingData
convenience init(withCryptKey key: StaticKey) throws {
self.init(serializer: try CryptSerializer(withKey: key))
}
private init(serializer: ControlChannelSerializer) {
self.serializer = serializer
sessionId = nil
remoteSessionId = nil
queue = BidirectionalState(withResetValue: [])
currentPacketId = BidirectionalState(withResetValue: 0)
pendingAcks = []
plainBuffer = Z(count: TLSBoxMaxBufferLength)
dataCount = BidirectionalState(withResetValue: 0)
}
func reset(forNewSession: Bool) throws {
if forNewSession {
try sessionId = SecureRandom.data(length: PacketSessionIdLength)
private var dataCount: BidirectionalState<Int>
convenience init() {
self.init(serializer: PlainSerializer())
}
convenience init(withAuthKey key: StaticKey, digest: Digest) throws {
self.init(serializer: try AuthSerializer(withKey: key, digest: digest))
}
convenience init(withCryptKey key: StaticKey) throws {
self.init(serializer: try CryptSerializer(withKey: key))
}
private init(serializer: ControlChannelSerializer) {
self.serializer = serializer
sessionId = nil
remoteSessionId = nil
queue = BidirectionalState(withResetValue: [])
currentPacketId = BidirectionalState(withResetValue: 0)
pendingAcks = []
plainBuffer = Z(count: TLSBoxMaxBufferLength)
dataCount = BidirectionalState(withResetValue: 0)
}
queue.reset()
currentPacketId.reset()
pendingAcks.removeAll()
plainBuffer.zero()
dataCount.reset()
serializer.reset()
}
func readInboundPacket(withData data: Data, offset: Int) throws -> ControlPacket {
let packet = try serializer.deserialize(data: data, start: offset, end: nil)
log.debug("Control: Read packet \(packet)")
if let ackIds = packet.ackIds as? [UInt32], let ackRemoteSessionId = packet.ackRemoteSessionId {
try readAcks(ackIds, acksRemoteSessionId: ackRemoteSessionId)
}
return packet
}
func enqueueInboundPacket(packet: ControlPacket) -> [ControlPacket] {
queue.inbound.append(packet)
queue.inbound.sort { $0.packetId < $1.packetId }
var toHandle: [ControlPacket] = []
for queuedPacket in queue.inbound {
if queuedPacket.packetId < currentPacketId.inbound {
queue.inbound.removeFirst()
continue
func reset(forNewSession: Bool) throws {
if forNewSession {
try sessionId = SecureRandom.data(length: PacketSessionIdLength)
remoteSessionId = nil
}
if queuedPacket.packetId != currentPacketId.inbound {
continue
}
toHandle.append(queuedPacket)
currentPacketId.inbound += 1
queue.inbound.removeFirst()
}
return toHandle
}
func enqueueOutboundPackets(withCode code: PacketCode, key: UInt8, payload: Data, maxPacketSize: Int) {
guard let sessionId = sessionId else {
fatalError("Missing sessionId, do reset(forNewSession: true) first")
queue.reset()
currentPacketId.reset()
pendingAcks.removeAll()
plainBuffer.zero()
dataCount.reset()
serializer.reset()
}
let oldIdOut = currentPacketId.outbound
var queuedCount = 0
var offset = 0
repeat {
let subPayloadLength = min(maxPacketSize, payload.count - offset)
let subPayloadData = payload.subdata(offset: offset, count: subPayloadLength)
let packet = ControlPacket(code: code, key: key, sessionId: sessionId, packetId: currentPacketId.outbound, payload: subPayloadData)
queue.outbound.append(packet)
currentPacketId.outbound += 1
offset += maxPacketSize
queuedCount += subPayloadLength
} while (offset < payload.count)
assert(queuedCount == payload.count)
// packet count
let packetCount = currentPacketId.outbound - oldIdOut
if (packetCount > 1) {
log.debug("Control: Enqueued \(packetCount) packets [\(oldIdOut)-\(currentPacketId.outbound - 1)]")
} else {
log.debug("Control: Enqueued 1 packet [\(oldIdOut)]")
func readInboundPacket(withData data: Data, offset: Int) throws -> ControlPacket {
let packet = try serializer.deserialize(data: data, start: offset, end: nil)
log.debug("Control: Read packet \(packet)")
if let ackIds = packet.ackIds as? [UInt32], let ackRemoteSessionId = packet.ackRemoteSessionId {
try readAcks(ackIds, acksRemoteSessionId: ackRemoteSessionId)
}
return packet
}
}
func writeOutboundPackets() throws -> [Data] {
var rawList: [Data] = []
for packet in queue.outbound {
if let sentDate = packet.sentDate {
let timeAgo = -sentDate.timeIntervalSinceNow
guard (timeAgo >= CoreConfiguration.OpenVPN.retransmissionLimit) else {
log.debug("Control: Skip writing packet with packetId \(packet.packetId) (sent on \(sentDate), \(timeAgo) seconds ago)")
func enqueueInboundPacket(packet: ControlPacket) -> [ControlPacket] {
queue.inbound.append(packet)
queue.inbound.sort { $0.packetId < $1.packetId }
var toHandle: [ControlPacket] = []
for queuedPacket in queue.inbound {
if queuedPacket.packetId < currentPacketId.inbound {
queue.inbound.removeFirst()
continue
}
if queuedPacket.packetId != currentPacketId.inbound {
continue
}
toHandle.append(queuedPacket)
currentPacketId.inbound += 1
queue.inbound.removeFirst()
}
return toHandle
}
func enqueueOutboundPackets(withCode code: PacketCode, key: UInt8, payload: Data, maxPacketSize: Int) {
guard let sessionId = sessionId else {
fatalError("Missing sessionId, do reset(forNewSession: true) first")
}
let oldIdOut = currentPacketId.outbound
var queuedCount = 0
var offset = 0
repeat {
let subPayloadLength = min(maxPacketSize, payload.count - offset)
let subPayloadData = payload.subdata(offset: offset, count: subPayloadLength)
let packet = ControlPacket(code: code, key: key, sessionId: sessionId, packetId: currentPacketId.outbound, payload: subPayloadData)
queue.outbound.append(packet)
currentPacketId.outbound += 1
offset += maxPacketSize
queuedCount += subPayloadLength
} while (offset < payload.count)
assert(queuedCount == payload.count)
// packet count
let packetCount = currentPacketId.outbound - oldIdOut
if (packetCount > 1) {
log.debug("Control: Enqueued \(packetCount) packets [\(oldIdOut)-\(currentPacketId.outbound - 1)]")
} else {
log.debug("Control: Enqueued 1 packet [\(oldIdOut)]")
}
}
func writeOutboundPackets() throws -> [Data] {
var rawList: [Data] = []
for packet in queue.outbound {
if let sentDate = packet.sentDate {
let timeAgo = -sentDate.timeIntervalSinceNow
guard (timeAgo >= CoreConfiguration.OpenVPN.retransmissionLimit) else {
log.debug("Control: Skip writing packet with packetId \(packet.packetId) (sent on \(sentDate), \(timeAgo) seconds ago)")
continue
}
}
log.debug("Control: Write control packet \(packet)")
let raw = try serializer.serialize(packet: packet)
rawList.append(raw)
packet.sentDate = Date()
// track pending acks for sent packets
pendingAcks.insert(packet.packetId)
}
// log.verbose("Packets now pending ack: \(pendingAcks)")
return rawList
}
func hasPendingAcks() -> Bool {
return !pendingAcks.isEmpty
}
// Ruby: handle_acks
private func readAcks(_ packetIds: [UInt32], acksRemoteSessionId: Data) throws {
guard let sessionId = sessionId else {
throw OpenVPNError.missingSessionId
}
guard acksRemoteSessionId == sessionId else {
log.error("Control: Ack session mismatch (\(acksRemoteSessionId.toHex()) != \(sessionId.toHex()))")
throw OpenVPNError.sessionMismatch
}
// drop queued out packets if ack-ed
for (i, packet) in queue.outbound.enumerated() {
if packetIds.contains(packet.packetId) {
queue.outbound.remove(at: i)
}
}
log.debug("Control: Write control packet \(packet)")
let raw = try serializer.serialize(packet: packet)
rawList.append(raw)
packet.sentDate = Date()
// track pending acks for sent packets
pendingAcks.insert(packet.packetId)
}
// log.verbose("Packets now pending ack: \(pendingAcks)")
return rawList
}
func hasPendingAcks() -> Bool {
return !pendingAcks.isEmpty
}
// Ruby: handle_acks
private func readAcks(_ packetIds: [UInt32], acksRemoteSessionId: Data) throws {
guard let sessionId = sessionId else {
throw SessionError.missingSessionId
}
guard acksRemoteSessionId == sessionId else {
log.error("Control: Ack session mismatch (\(acksRemoteSessionId.toHex()) != \(sessionId.toHex()))")
throw SessionError.sessionMismatch
// remove ack-ed packets from pending
pendingAcks.subtract(packetIds)
// log.verbose("Packets still pending ack: \(pendingAcks)")
}
// drop queued out packets if ack-ed
for (i, packet) in queue.outbound.enumerated() {
if packetIds.contains(packet.packetId) {
queue.outbound.remove(at: i)
func writeAcks(withKey key: UInt8, ackPacketIds: [UInt32], ackRemoteSessionId: Data) throws -> Data {
guard let sessionId = sessionId else {
throw OpenVPNError.missingSessionId
}
let packet = ControlPacket(key: key, sessionId: sessionId, ackIds: ackPacketIds as [NSNumber], ackRemoteSessionId: ackRemoteSessionId)
log.debug("Control: Write ack packet \(packet)")
return try serializer.serialize(packet: packet)
}
// remove ack-ed packets from pending
pendingAcks.subtract(packetIds)
// log.verbose("Packets still pending ack: \(pendingAcks)")
}
func writeAcks(withKey key: UInt8, ackPacketIds: [UInt32], ackRemoteSessionId: Data) throws -> Data {
guard let sessionId = sessionId else {
throw SessionError.missingSessionId
func currentControlData(withTLS tls: TLSBox) throws -> ZeroingData {
var length = 0
try tls.pullRawPlainText(plainBuffer.mutableBytes, length: &length)
return plainBuffer.withOffset(0, count: length)
}
func addReceivedDataCount(_ count: Int) {
dataCount.inbound += count
}
let packet = ControlPacket(key: key, sessionId: sessionId, ackIds: ackPacketIds as [NSNumber], ackRemoteSessionId: ackRemoteSessionId)
log.debug("Control: Write ack packet \(packet)")
return try serializer.serialize(packet: packet)
}
func currentControlData(withTLS tls: TLSBox) throws -> ZeroingData {
var length = 0
try tls.pullRawPlainText(plainBuffer.mutableBytes, length: &length)
return plainBuffer.withOffset(0, count: length)
}
func addReceivedDataCount(_ count: Int) {
dataCount.inbound += count
}
func addSentDataCount(_ count: Int) {
dataCount.outbound += count
}
func currentDataCount() -> (Int, Int) {
return dataCount.pair
func addSentDataCount(_ count: Int) {
dataCount.outbound += count
}
func currentDataCount() -> (Int, Int) {
return dataCount.pair
}
}
}

View File

@ -38,7 +38,7 @@ protocol ControlChannelSerializer {
func deserialize(data: Data, start: Int, end: Int?) throws -> ControlPacket
}
extension ControlChannel {
extension OpenVPN.ControlChannel {
class PlainSerializer: ControlChannelSerializer {
func reset() {
}
@ -52,11 +52,11 @@ extension ControlChannel {
let end = end ?? packet.count
guard end >= offset + PacketOpcodeLength else {
throw ControlChannelError("Missing opcode")
throw OpenVPN.ControlChannelError("Missing opcode")
}
let codeValue = packet[offset] >> 3
guard let code = PacketCode(rawValue: codeValue) else {
throw ControlChannelError("Unknown code: \(codeValue))")
throw OpenVPN.ControlChannelError("Unknown code: \(codeValue))")
}
let key = packet[offset] & 0b111
offset += PacketOpcodeLength
@ -64,13 +64,13 @@ extension ControlChannel {
log.debug("Control: Try read packet with code \(code) and key \(key)")
guard end >= offset + PacketSessionIdLength else {
throw ControlChannelError("Missing sessionId")
throw OpenVPN.ControlChannelError("Missing sessionId")
}
let sessionId = packet.subdata(offset: offset, count: PacketSessionIdLength)
offset += PacketSessionIdLength
guard end >= offset + 1 else {
throw ControlChannelError("Missing ackSize")
throw OpenVPN.ControlChannelError("Missing ackSize")
}
let ackSize = packet[offset]
offset += 1
@ -79,7 +79,7 @@ extension ControlChannel {
var ackRemoteSessionId: Data?
if ackSize > 0 {
guard end >= (offset + Int(ackSize) * PacketIdLength) else {
throw ControlChannelError("Missing acks")
throw OpenVPN.ControlChannelError("Missing acks")
}
var ids: [UInt32] = []
for _ in 0..<ackSize {
@ -89,7 +89,7 @@ extension ControlChannel {
}
guard end >= offset + PacketSessionIdLength else {
throw ControlChannelError("Missing remoteSessionId")
throw OpenVPN.ControlChannelError("Missing remoteSessionId")
}
let remoteSessionId = packet.subdata(offset: offset, count: PacketSessionIdLength)
offset += PacketSessionIdLength
@ -100,16 +100,16 @@ extension ControlChannel {
if code == .ackV1 {
guard let ackIds = ackIds else {
throw ControlChannelError("Ack packet without ids")
throw OpenVPN.ControlChannelError("Ack packet without ids")
}
guard let ackRemoteSessionId = ackRemoteSessionId else {
throw ControlChannelError("Ack packet without remoteSessionId")
throw OpenVPN.ControlChannelError("Ack packet without remoteSessionId")
}
return ControlPacket(key: key, sessionId: sessionId, ackIds: ackIds as [NSNumber], ackRemoteSessionId: ackRemoteSessionId)
}
guard end >= offset + PacketIdLength else {
throw ControlChannelError("Missing packetId")
throw OpenVPN.ControlChannelError("Missing packetId")
}
let packetId = packet.networkUInt32Value(from: offset)
offset += PacketIdLength
@ -129,7 +129,7 @@ extension ControlChannel {
}
}
extension ControlChannel {
extension OpenVPN.ControlChannel {
class AuthSerializer: ControlChannelSerializer {
private let encrypter: Encrypter
@ -149,7 +149,7 @@ extension ControlChannel {
private let plain: PlainSerializer
init(withKey key: StaticKey, digest: SessionProxy.Digest) throws {
init(withKey key: OpenVPN.StaticKey, digest: OpenVPN.Digest) throws {
let crypto = CryptoBox(cipherAlgorithm: nil, digestAlgorithm: digest.rawValue)
try crypto.configure(
withCipherEncKey: nil,
@ -190,7 +190,7 @@ extension ControlChannel {
// data starts with (prefix=(header + sessionId) + auth=(hmac + replayId))
guard end >= preambleLength else {
throw ControlChannelError("Missing HMAC")
throw OpenVPN.ControlChannelError("Missing HMAC")
}
// needs a copy for swapping
@ -209,7 +209,7 @@ extension ControlChannel {
}
}
extension ControlChannel {
extension OpenVPN.ControlChannel {
class CryptSerializer: ControlChannelSerializer {
private let encrypter: Encrypter
@ -227,7 +227,7 @@ extension ControlChannel {
private let plain: PlainSerializer
init(withKey key: StaticKey) throws {
init(withKey key: OpenVPN.StaticKey) throws {
let crypto = CryptoBox(cipherAlgorithm: "AES-256-CTR", digestAlgorithm: "SHA256")
try crypto.configure(
withCipherEncKey: key.cipherEncryptKey,
@ -267,7 +267,7 @@ extension ControlChannel {
// data starts with (ad=(header + sessionId + replayId) + tag)
guard end >= start + adLength + tagLength else {
throw ControlChannelError("Missing AD+TAG")
throw OpenVPN.ControlChannelError("Missing AD+TAG")
}
let encryptedCount = packet.count - adLength

View File

@ -37,58 +37,59 @@
import Foundation
import __TunnelKitOpenVPN
/// Represents a cryptographic container in PEM format.
public struct CryptoContainer: Equatable {
private static let begin = "-----BEGIN "
extension OpenVPN {
private static let end = "-----END "
/// The content in PEM format (ASCII).
public let pem: String
/// :nodoc:
public init(pem: String) {
guard let beginRange = pem.range(of: CryptoContainer.begin) else {
self.pem = ""
return
/// Represents a cryptographic container in PEM format.
public struct CryptoContainer: Codable, Equatable {
private static let begin = "-----BEGIN "
private static let end = "-----END "
/// The content in PEM format (ASCII).
public let pem: String
var isEncrypted: Bool {
return pem.contains("ENCRYPTED")
}
/// :nodoc:
public init(pem: String) {
guard let beginRange = pem.range(of: CryptoContainer.begin) else {
self.pem = ""
return
}
self.pem = String(pem[beginRange.lowerBound...])
}
func write(to url: URL) throws {
try pem.write(to: url, atomically: true, encoding: .ascii)
}
self.pem = String(pem[beginRange.lowerBound...])
}
func write(to url: URL) throws {
try pem.write(to: url, atomically: true, encoding: .ascii)
}
// MARK: Equatable
/// :nodoc:
public static func ==(lhs: CryptoContainer, rhs: CryptoContainer) -> Bool {
return lhs.pem == rhs.pem
}
}
/// :nodoc:
extension CryptoContainer: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let pem = try container.decode(String.self)
self.init(pem: pem)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(pem)
}
}
/// :nodoc:
public extension CryptoContainer {
var isEncrypted: Bool {
return pem.contains("ENCRYPTED")
}
func decrypted(with passphrase: String) throws -> CryptoContainer {
let decryptedPEM = try TLSBox.decryptedPrivateKey(fromPEM: pem, passphrase: passphrase)
return CryptoContainer(pem: decryptedPEM)
func decrypted(with passphrase: String) throws -> CryptoContainer {
let decryptedPEM = try TLSBox.decryptedPrivateKey(fromPEM: pem, passphrase: passphrase)
return CryptoContainer(pem: decryptedPEM)
}
// MARK: Equatable
/// :nodoc:
public static func ==(lhs: CryptoContainer, rhs: CryptoContainer) -> Bool {
return lhs.pem == rhs.pem
}
// MARK: Codable
/// :nodoc:
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let pem = try container.decode(String.self)
self.init(pem: pem)
}
/// :nodoc:
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(pem)
}
}
}

View File

@ -1,5 +1,5 @@
//
// SessionProxy+EncryptionBridge.swift
// EncryptionBridge.swift
// TunnelKit
//
// Created by Davide De Rosa on 2/8/17.
@ -38,29 +38,12 @@ import Foundation
import __TunnelKitCore
import __TunnelKitOpenVPN
extension SessionProxy {
/// Bridges native encryption for high-level operations.
public class EncryptionBridge {
extension OpenVPN {
class EncryptionBridge {
private static let maxHmacLength = 100
private let box: CryptoBox
/**
Initializes the PRNG. Must be issued before using `SessionProxy`.
- Parameter seedLength: The length in bytes of the pseudorandom seed that will feed the PRNG.
*/
public static func prepareRandomNumberGenerator(seedLength: Int) -> Bool {
let seed: ZeroingData
do {
seed = try SecureRandom.safeData(length: seedLength)
} catch {
return false
}
return CryptoBox.preparePRNG(withSeed: seed.bytes, length: seed.count)
}
// Ruby: keys_prf
private static func keysPRF(
_ label: String,
@ -127,7 +110,7 @@ extension SessionProxy {
return buffer.withOffset(0, count: length)
}
convenience init(_ cipher: SessionProxy.Cipher, _ digest: SessionProxy.Digest, _ auth: SessionProxy.Authenticator,
convenience init(_ cipher: Cipher, _ digest: Digest, _ auth: Authenticator,
_ sessionId: Data, _ remoteSessionId: Data) throws {
guard let serverRandom1 = auth.serverRandom1, let serverRandom2 = auth.serverRandom2 else {
@ -161,7 +144,7 @@ extension SessionProxy {
try self.init(cipher, digest, cipherEncKey, cipherDecKey, hmacEncKey, hmacDecKey)
}
init(_ cipher: SessionProxy.Cipher, _ digest: SessionProxy.Digest, _ cipherEncKey: ZeroingData, _ cipherDecKey: ZeroingData, _ hmacEncKey: ZeroingData, _ hmacDecKey: ZeroingData) throws {
init(_ cipher: Cipher, _ digest: Digest, _ cipherEncKey: ZeroingData, _ cipherDecKey: ZeroingData, _ hmacEncKey: ZeroingData, _ hmacDecKey: ZeroingData) throws {
box = CryptoBox(cipherAlgorithm: cipher.rawValue, digestAlgorithm: digest.rawValue)
try box.configure(
withCipherEncKey: cipherEncKey,

View File

@ -0,0 +1,48 @@
//
// OpenVPN.swift
// TunnelKit
//
// Created by Davide De Rosa on 5/19/19.
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
//
// https://github.com/passepartoutvpn
//
// 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/>.
//
import Foundation
import __TunnelKitCore
import __TunnelKitOpenVPN
/// Container for OpenVPN classes.
public class OpenVPN {
/**
Initializes the PRNG. Must be issued before using `OpenVPNSession`.
- Parameter seedLength: The length in bytes of the pseudorandom seed that will feed the PRNG.
*/
public static func prepareRandomNumberGenerator(seedLength: Int) -> Bool {
let seed: ZeroingData
do {
seed = try SecureRandom.safeData(length: seedLength)
} catch {
return false
}
return CryptoBox.preparePRNG(withSeed: seed.bytes, length: seed.count)
}
}

View File

@ -1,5 +1,5 @@
//
// SessionError.swift
// OpenVPNError.swift
// TunnelKit
//
// Created by Davide De Rosa on 8/23/18.
@ -35,10 +35,9 @@
//
import Foundation
import __TunnelKitCore
/// The possible errors raised/thrown during `SessionProxy` operation.
public enum SessionError: String, Error {
/// The possible errors raised/thrown during `OpenVPNSession` operation.
public enum OpenVPNError: String, Error {
/// The negotiation timed out.
case negotiationTimeout
@ -79,18 +78,3 @@ public enum SessionError: String, Error {
/// Missing routing information.
case noRouting
}
extension Error {
func isTunnelKitError() -> Bool {
let te = self as NSError
return te.domain == TunnelKitErrorDomain
}
func tunnelKitErrorCode() -> TunnelKitErrorCode? {
let te = self as NSError
guard te.domain == TunnelKitErrorDomain else {
return nil
}
return TunnelKitErrorCode(rawValue: te.code)
}
}

View File

@ -1,5 +1,5 @@
//
// SessionProxy+PIA.swift
// OpenVPNSession+PIA.swift
// TunnelKit
//
// Created by Davide De Rosa on 10/18/18.
@ -36,7 +36,7 @@
import Foundation
extension SessionProxy {
extension OpenVPNSession {
struct PIAHardReset {
private static let obfuscationKeyLength = 3
@ -50,7 +50,7 @@ extension SessionProxy {
private let digestName: String
init(caMd5Digest: String, cipher: Cipher, digest: Digest) {
init(caMd5Digest: String, cipher: OpenVPN.Cipher, digest: OpenVPN.Digest) {
self.caMd5Digest = caMd5Digest
cipherName = cipher.rawValue.lowercased()
digestName = digest.rawValue.lowercased()

View File

@ -1,5 +1,5 @@
//
// SessionProxy.swift
// OpenVPNSession.swift
// TunnelKit
//
// Created by Davide De Rosa on 2/3/17.
@ -41,28 +41,28 @@ import __TunnelKitOpenVPN
private let log = SwiftyBeaver.self
/// Observes major events notified by a `SessionProxy`.
public protocol SessionProxyDelegate: class {
/// Observes major events notified by a `OpenVPNSession`.
public protocol OpenVPNSessionDelegate: class {
/**
Called after starting a session.
- Parameter remoteAddress: The address of the VPN server.
- Parameter reply: The compound `SessionReply` containing tunnel settings.
- Parameter options: The pulled tunnel settings.
*/
func sessionDidStart(_: SessionProxy, remoteAddress: String, reply: SessionReply)
func sessionDidStart(_: OpenVPNSession, remoteAddress: String, options: OpenVPN.Configuration)
/**
Called after stopping a session.
- Parameter shouldReconnect: When `true`, the session can/should be restarted. Usually because the stop reason was recoverable.
- Seealso: `SessionProxy.reconnect(...)`
- Seealso: `OpenVPNSession.reconnect(...)`
*/
func sessionDidStop(_: SessionProxy, shouldReconnect: Bool)
func sessionDidStop(_: OpenVPNSession, shouldReconnect: Bool)
}
/// Provides methods to set up and maintain an OpenVPN session.
public class SessionProxy {
public class OpenVPNSession: Session {
private enum StopMethod {
case shutdown
@ -80,10 +80,10 @@ public class SessionProxy {
// MARK: Configuration
/// The session base configuration.
public let configuration: Configuration
public let configuration: OpenVPN.Configuration
/// The optional credentials.
public var credentials: Credentials?
public var credentials: OpenVPN.Credentials?
private var keepAliveInterval: TimeInterval? {
let interval: TimeInterval?
@ -97,8 +97,8 @@ public class SessionProxy {
return interval
}
/// An optional `SessionProxyDelegate` for receiving session events.
public weak var delegate: SessionProxyDelegate?
/// An optional `OpenVPNSessionDelegate` for receiving session events.
public weak var delegate: OpenVPNSessionDelegate?
// MARK: State
@ -108,22 +108,22 @@ public class SessionProxy {
private var withLocalOptions: Bool
private var keys: [UInt8: SessionKey]
private var keys: [UInt8: OpenVPN.SessionKey]
private var oldKeys: [SessionKey]
private var oldKeys: [OpenVPN.SessionKey]
private var negotiationKeyIdx: UInt8
private var currentKeyIdx: UInt8?
private var negotiationKey: SessionKey {
private var negotiationKey: OpenVPN.SessionKey {
guard let key = keys[negotiationKeyIdx] else {
fatalError("Keys are empty or index \(negotiationKeyIdx) not found in \(keys.keys)")
}
return key
}
private var currentKey: SessionKey? {
private var currentKey: OpenVPN.SessionKey? {
guard let i = currentKeyIdx else {
return nil
}
@ -140,7 +140,7 @@ public class SessionProxy {
private var continuatedPushReplyMessage: String?
private var pushReply: SessionReply?
private var pushReply: OpenVPN.PushReply?
private var nextPushRequestDate: Date?
@ -155,9 +155,9 @@ public class SessionProxy {
// MARK: Control
private var controlChannel: ControlChannel
private var controlChannel: OpenVPN.ControlChannel
private var authenticator: Authenticator?
private var authenticator: OpenVPN.Authenticator?
// MARK: Caching
@ -181,9 +181,9 @@ public class SessionProxy {
Creates a VPN session.
- Parameter queue: The `DispatchQueue` where to run the session loop.
- Parameter configuration: The `SessionProxy.Configuration` to use for this session.
- Parameter configuration: The `Configuration` to use for this session.
*/
public init(queue: DispatchQueue, configuration: Configuration, cachesURL: URL) throws {
public init(queue: DispatchQueue, configuration: OpenVPN.Configuration, cachesURL: URL) throws {
guard let ca = configuration.ca else {
throw ConfigurationError.missingConfiguration(option: "ca")
}
@ -202,13 +202,13 @@ public class SessionProxy {
if let tlsWrap = configuration.tlsWrap {
switch tlsWrap.strategy {
case .auth:
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest)
controlChannel = try OpenVPN.ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest)
case .crypt:
controlChannel = try ControlChannel(withCryptKey: tlsWrap.key)
controlChannel = try OpenVPN.ControlChannel(withCryptKey: tlsWrap.key)
}
} else {
controlChannel = ControlChannel()
controlChannel = OpenVPN.ControlChannel()
}
// cache PEMs locally (mandatory for OpenSSL)
@ -236,15 +236,8 @@ public class SessionProxy {
}
}
// MARK: Public interface
// MARK: Session
/**
Establishes the link interface for this session. The interface must be up and running for sending and receiving packets.
- Precondition: `link` is an active network interface.
- Postcondition: The VPN negotiation is started.
- Parameter link: The `LinkInterface` on which to establish the VPN session.
*/
public func setLink(_ link: LinkInterface) {
guard (self.link == nil) else {
log.warning("Link interface already set!")
@ -265,11 +258,6 @@ public class SessionProxy {
start()
}
/**
Returns `true` if the current session can rebind to a new link with `rebindLink(...)`.
- Returns: `true` if supports link rebinding.
*/
public func canRebindLink() -> Bool {
// return (pushReply?.peerId != nil)
@ -277,14 +265,6 @@ public class SessionProxy {
return false
}
/**
Rebinds the session to a new link if supported.
- Precondition: `link` is an active network interface.
- Postcondition: The VPN session is active.
- Parameter link: The `LinkInterface` on which to establish the VPN session.
- Seealso: `canRebindLink()`.
*/
public func rebindLink(_ link: LinkInterface) {
guard let _ = pushReply?.options.peerId else {
log.warning("Session doesn't support link rebinding!")
@ -299,13 +279,6 @@ public class SessionProxy {
loopLink()
}
/**
Establishes the tunnel interface for this session. The interface must be up and running for sending and receiving packets.
- Precondition: `tunnel` is an active network interface.
- Postcondition: The VPN data channel is open.
- Parameter tunnel: The `TunnelInterface` on which to exchange the VPN data traffic.
*/
public func setTunnel(tunnel: TunnelInterface) {
guard (self.tunnel == nil) else {
log.warning("Tunnel interface already set!")
@ -315,11 +288,6 @@ public class SessionProxy {
loopTunnel()
}
/**
Returns the current data bytes count.
- Returns: The current data bytes count as a pair, inbound first.
*/
public func dataCount() -> (Int, Int)? {
guard let _ = link else {
return nil
@ -327,11 +295,6 @@ public class SessionProxy {
return controlChannel.currentDataCount()
}
/**
Shuts down the session with an optional `Error` reason. Does nothing if the session is already stopped or about to stop.
- Parameter error: An optional `Error` being the reason of the shutdown.
*/
public func shutdown(error: Error?) {
guard !isStopping else {
log.warning("Ignore stop request, already stopping!")
@ -340,12 +303,6 @@ public class SessionProxy {
deferStop(.shutdown, error)
}
/**
Shuts down the session with an optional `Error` reason and signals a reconnect flag to `SessionProxyDelegate.sessionDidStop(...)`. Does nothing if the session is already stopped or about to stop.
- Parameter error: An optional `Error` being the reason of the shutdown.
- Seealso: `SessionProxyDelegate.sessionDidStop(...)`
*/
public func reconnect(error: Error?) {
guard !isStopping else {
log.warning("Ignore stop request, already stopping!")
@ -355,9 +312,6 @@ public class SessionProxy {
}
// Ruby: cleanup
/**
Cleans up the session resources.
*/
public func cleanup() {
log.info("Cleaning up...")
@ -402,14 +356,14 @@ public class SessionProxy {
}
guard !negotiationKey.didHardResetTimeOut(link: link) else {
doReconnect(error: SessionError.negotiationTimeout)
doReconnect(error: OpenVPNError.negotiationTimeout)
return
}
guard !negotiationKey.didNegotiationTimeOut(link: link) else {
doShutdown(error: SessionError.negotiationTimeout)
doShutdown(error: OpenVPNError.negotiationTimeout)
return
}
pushRequest()
if !isReliableLink {
flushControlQueue()
@ -499,7 +453,7 @@ public class SessionProxy {
let key = firstByte & 0b111
guard let _ = keys[key] else {
log.error("Key with id \(key) not found")
deferStop(.shutdown, SessionError.badKey)
deferStop(.shutdown, OpenVPNError.badKey)
return
}
@ -526,7 +480,7 @@ public class SessionProxy {
// return
}
if (code == .hardResetServerV2) && (negotiationKey.controlState == .connected) {
deferStop(.shutdown, SessionError.staleSession)
deferStop(.shutdown, OpenVPNError.staleSession)
return
} else if (code == .softResetV1) && !negotiationKey.softReset {
softReset(isServerInitiated: true)
@ -567,7 +521,7 @@ public class SessionProxy {
let now = Date()
guard (now.timeIntervalSince(lastPing.inbound) <= CoreConfiguration.OpenVPN.pingTimeout) else {
deferStop(.shutdown, SessionError.pingTimeout)
deferStop(.shutdown, OpenVPNError.pingTimeout)
return
}
@ -581,7 +535,7 @@ public class SessionProxy {
}
log.debug("Send ping")
sendDataPackets([DataPacket.pingString])
sendDataPackets([OpenVPN.DataPacket.pingString])
lastPing.outbound = Date()
scheduleNextPing()
@ -617,7 +571,7 @@ public class SessionProxy {
continuatedPushReplyMessage = nil
pushReply = nil
negotiationKeyIdx = 0
let newKey = SessionKey(id: UInt8(negotiationKeyIdx))
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)")
@ -658,8 +612,8 @@ public class SessionProxy {
}
resetControlChannel(forNewSession: false)
negotiationKeyIdx = max(1, (negotiationKeyIdx + 1) % ProtocolMacros.numberOfKeys)
let newKey = SessionKey(id: UInt8(negotiationKeyIdx))
negotiationKeyIdx = max(1, (negotiationKeyIdx + 1) % OpenVPN.ProtocolMacros.numberOfKeys)
let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)")
@ -678,7 +632,7 @@ public class SessionProxy {
negotiationKey.controlState = .preAuth
do {
authenticator = try Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
authenticator = try OpenVPN.Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
authenticator?.withLocalOptions = withLocalOptions
try authenticator?.putAuth(into: negotiationKey.tls, options: configuration)
} catch let e {
@ -766,7 +720,7 @@ public class SessionProxy {
private func handleControlPacket(_ packet: ControlPacket) {
guard packet.key == negotiationKey.id else {
log.error("Bad key in control packet (\(packet.key) != \(negotiationKey.id))")
// deferStop(.shutdown, SessionError.badKey)
// deferStop(.shutdown, OpenVPNError.badKey)
return
}
@ -779,12 +733,12 @@ public class SessionProxy {
}
guard let remoteSessionId = controlChannel.remoteSessionId else {
log.error("No remote sessionId (never set)")
deferStop(.shutdown, SessionError.missingSessionId)
deferStop(.shutdown, OpenVPNError.missingSessionId)
return
}
guard packet.sessionId == remoteSessionId else {
log.error("Packet session mismatch (\(packet.sessionId.toHex()) != \(remoteSessionId.toHex()))")
deferStop(.shutdown, SessionError.sessionMismatch)
deferStop(.shutdown, OpenVPNError.sessionMismatch)
return
}
@ -829,12 +783,12 @@ public class SessionProxy {
else if ((packet.code == .controlV1) && (negotiationKey.state == .tls)) {
guard let remoteSessionId = controlChannel.remoteSessionId else {
log.error("No remote sessionId found in packet (control packets before server HARD_RESET)")
deferStop(.shutdown, SessionError.missingSessionId)
deferStop(.shutdown, OpenVPNError.missingSessionId)
return
}
guard packet.sessionId == remoteSessionId else {
log.error("Packet session mismatch (\(packet.sessionId.toHex()) != \(remoteSessionId.toHex()))")
deferStop(.shutdown, SessionError.sessionMismatch)
deferStop(.shutdown, OpenVPNError.sessionMismatch)
return
}
@ -921,11 +875,11 @@ public class SessionProxy {
if authenticator?.withLocalOptions ?? false {
log.warning("Authentication failure, retrying without local options")
withLocalOptions = false
deferStop(.reconnect, SessionError.badCredentials)
deferStop(.reconnect, OpenVPNError.badCredentials)
return
}
deferStop(.shutdown, SessionError.badCredentials)
deferStop(.shutdown, OpenVPNError.badCredentials)
return
}
@ -943,9 +897,9 @@ public class SessionProxy {
} else {
completeMessage = message
}
let reply: PushReply
let reply: OpenVPN.PushReply
do {
guard let optionalReply = try PushReply(message: completeMessage) else {
guard let optionalReply = try OpenVPN.PushReply(message: completeMessage) else {
return
}
reply = optionalReply
@ -959,15 +913,15 @@ public class SessionProxy {
case .LZO:
if !LZOIsSupported() {
log.error("Server has LZO compression enabled and this was not built into the library (framing=\(framing))")
throw SessionError.serverCompression
throw OpenVPNError.serverCompression
}
case .other:
log.error("Server has non-LZO compression enabled and this is currently unsupported (framing=\(framing))")
throw SessionError.serverCompression
throw OpenVPNError.serverCompression
}
}
} catch SessionError.continuationPushReply {
} catch OpenVPNError.continuationPushReply {
continuatedPushReplyMessage = completeMessage.replacingOccurrences(of: "push-continuation", with: "")
// FIXME: strip "PUSH_REPLY" and "push-continuation 2"
return
@ -978,7 +932,7 @@ public class SessionProxy {
pushReply = reply
guard reply.options.ipv4 != nil || reply.options.ipv6 != nil else {
deferStop(.shutdown, SessionError.noRouting)
deferStop(.shutdown, OpenVPNError.noRouting)
return
}
@ -987,7 +941,7 @@ public class SessionProxy {
guard let remoteAddress = link?.remoteAddress else {
fatalError("Could not resolve link remote address")
}
delegate?.sessionDidStart(self, remoteAddress: remoteAddress, reply: reply)
delegate?.sessionDidStart(self, remoteAddress: remoteAddress, options: reply.options)
scheduleNextPing()
}
@ -1039,7 +993,7 @@ public class SessionProxy {
if let error = error {
self?.queue.sync {
log.error("Failed LINK write during control flush: \(error)")
self?.deferStop(.shutdown, SessionError.failedLinkWrite)
self?.deferStop(.shutdown, OpenVPNError.failedLinkWrite)
}
return
}
@ -1093,9 +1047,9 @@ public class SessionProxy {
log.info("\tNegotiated keep-alive: \(negPing) seconds")
}
let bridge: EncryptionBridge
let bridge: OpenVPN.EncryptionBridge
do {
bridge = try EncryptionBridge(
bridge = try OpenVPN.EncryptionBridge(
pushedCipher ?? configuration.fallbackCipher,
configuration.fallbackDigest,
auth,
@ -1121,7 +1075,7 @@ public class SessionProxy {
// MARK: Data
// Ruby: handle_data_pkt
private func handleDataPackets(_ packets: [Data], key: SessionKey) {
private func handleDataPackets(_ packets: [Data], key: OpenVPN.SessionKey) {
controlChannel.addReceivedDataCount(packets.flatCount)
do {
guard let decryptedPackets = try key.decrypt(packets: packets) else {
@ -1169,7 +1123,7 @@ public class SessionProxy {
self?.queue.sync {
log.error("Data: Failed LINK write during send data: \(error)")
self?.deferStop(.shutdown, SessionError.failedLinkWrite)
self?.deferStop(.shutdown, OpenVPNError.failedLinkWrite)
}
return
}
@ -1210,7 +1164,7 @@ public class SessionProxy {
if let error = error {
self?.queue.sync {
log.error("Failed LINK write during send ack for packetId \(controlPacket.packetId): \(error)")
self?.deferStop(.shutdown, SessionError.failedLinkWrite)
self?.deferStop(.shutdown, OpenVPNError.failedLinkWrite)
}
return
}
@ -1240,7 +1194,7 @@ public class SessionProxy {
// shut down after sending exit notification if socket is unreliable (normally UDP)
if let link = link, !link.isReliable {
do {
guard let packets = try currentKey?.encrypt(packets: [OCCPacket.exit.serialized()]) else {
guard let packets = try currentKey?.encrypt(packets: [OpenVPN.OCCPacket.exit.serialized()]) else {
completion()
return
}

View File

@ -37,66 +37,6 @@
import Foundation
import __TunnelKitOpenVPN
///// Reads and writes packets as a stream. Useful for stream-oriented links (e.g TCP/IP).
//public class PacketStream {
//
// /**
// Parses packets from a stream.
//
// - Parameter stream: The data stream.
// - Returns: A pair where the first value is the `Int` offset up to which
// the stream could be parsed, and the second value is an array containing
// the parsed packets up to such offset.
// */
// public static func packets(from stream: Data) -> (Int, [Data]) {
// var ni = 0
// var parsed: [Data] = []
// while (ni + 2 <= stream.count) {
// let packlen = Int(stream.networkUInt16Value(from: ni))
// let start = ni + 2
// let end = start + packlen
// guard (end <= stream.count) else {
// break
// }
// let packet = stream.subdata(offset: start, count: end - start)
// parsed.append(packet)
// ni = end
// }
// return (ni, parsed)
// }
//
// /**
// Creates a contiguous stream of packets.
//
// - Parameter packet: The packet.
// - Returns: A stream made of the packet.
// */
// public static func stream(from packet: Data) -> Data {
// var raw = Data(capacity: 2 + packet.count)
// raw.append(UInt16(packet.count).bigEndian)
// raw.append(contentsOf: packet)
// return raw
// }
//
// /**
// Creates a contiguous stream of packets.
//
// - Parameter packets: The array of packets.
// - Returns: A stream made of the array of packets.
// */
// public static func stream(from packets: [Data]) -> Data {
// var raw = Data()
// for payload in packets {
// raw.append(UInt16(payload.count).bigEndian)
// raw.append(payload)
// }
// return raw
// }
//
// private init() {
// }
//}
/// :nodoc:
extension ControlPacket {
@ -121,23 +61,25 @@ extension ControlPacket {
}
}
class DataPacket {
static let pingString = Data(hex: "2a187bf3641eb4cb07ed2d0a981fc748")
}
extension OpenVPN {
class DataPacket {
static let pingString = Data(hex: "2a187bf3641eb4cb07ed2d0a981fc748")
}
enum OCCPacket: UInt8 {
case exit = 0x06
private static let magicString = Data(hex: "287f346bd4ef7a812d56b8d3afc5459c")
enum OCCPacket: UInt8 {
case exit = 0x06
private static let magicString = Data(hex: "287f346bd4ef7a812d56b8d3afc5459c")
func serialized(_ info: Any? = nil) -> Data {
var data = OCCPacket.magicString
data.append(rawValue)
switch self {
case .exit:
break // nothing more
func serialized(_ info: Any? = nil) -> Data {
var data = OCCPacket.magicString
data.append(rawValue)
switch self {
case .exit:
break // nothing more
}
return data
}
return data
}
}

View File

@ -36,10 +36,12 @@
import Foundation
class ProtocolMacros {
// UInt32(0) + UInt8(KeyMethod = 2)
static let tlsPrefix = Data(hex: "0000000002")
extension OpenVPN {
class ProtocolMacros {
// UInt32(0) + UInt8(KeyMethod = 2)
static let tlsPrefix = Data(hex: "0000000002")
static let numberOfKeys = UInt8(8) // 3-bit
static let numberOfKeys = UInt8(8) // 3-bit
}
}

View File

@ -1,5 +1,5 @@
//
// SessionProxy+SessionReply.swift
// PushReply.swift
// TunnelKit
//
// Created by Davide De Rosa on 7/25/18.
@ -36,20 +36,13 @@
import Foundation
/// Groups the parsed reply of a successfully started session.
public protocol SessionReply {
/// The returned options.
var options: SessionProxy.Configuration { get }
}
extension SessionProxy {
struct PushReply: SessionReply, CustomStringConvertible {
extension OpenVPN {
struct PushReply: CustomStringConvertible {
private static let prefix = "PUSH_REPLY,"
private let original: String
let options: SessionProxy.Configuration
let options: Configuration
init?(message: String) throws {
guard message.hasPrefix(PushReply.prefix) else {
@ -66,6 +59,7 @@ extension SessionProxy {
// MARK: CustomStringConvertible
/// :nodoc:
var description: String {
let stripped = NSMutableString(string: original)
ConfigurationParser.Regex.authToken.replaceMatches(

View File

@ -1,5 +1,5 @@
//
// SessionProxy+SessionKey.swift
// SessionKey.swift
// TunnelKit
//
// Created by Davide De Rosa on 4/12/17.
@ -41,7 +41,7 @@ import __TunnelKitOpenVPN
private let log = SwiftyBeaver.self
extension SessionProxy {
extension OpenVPN {
class SessionKey {
enum State {
case invalid, hardReset, softReset, tls

View File

@ -26,207 +26,210 @@
import Foundation
import __TunnelKitCore
/// Represents an OpenVPN static key file (as generated with --genkey)
public class StaticKey: Codable {
enum CodingKeys: CodingKey {
case data
extension OpenVPN {
/// Represents an OpenVPN static key file (as generated with --genkey)
public class StaticKey: Codable {
enum CodingKeys: CodingKey {
case data
case dir
}
/// The key-direction field, usually 0 on servers and 1 on clients.
public enum Direction: Int, Codable {
/// Conventional server direction (implicit for tls-crypt).
case server = 0
/// Conventional client direction (implicit for tls-crypt).
case client = 1
}
case dir
}
/// The key-direction field, usually 0 on servers and 1 on clients.
public enum Direction: Int, Codable {
/// Conventional server direction (implicit for tls-crypt).
case server = 0
private static let contentLength = 256 // 2048-bit
/// Conventional client direction (implicit for tls-crypt).
case client = 1
}
private static let contentLength = 256 // 2048-bit
private static let keyCount = 4
private static let keyLength = StaticKey.contentLength / StaticKey.keyCount
private static let keyCount = 4
private static let keyLength = StaticKey.contentLength / StaticKey.keyCount
private static let fileHead = "-----BEGIN OpenVPN Static key V1-----"
private static let fileFoot = "-----END OpenVPN Static key V1-----"
private static let nonHexCharset = CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted
private let secureData: ZeroingData
private static let fileHead = "-----BEGIN OpenVPN Static key V1-----"
private static let fileFoot = "-----END OpenVPN Static key V1-----"
private static let nonHexCharset = CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted
private let secureData: ZeroingData
let direction: Direction?
/// Returns the encryption key.
///
/// - Precondition: `direction` must be non-nil.
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
public var cipherEncryptKey: ZeroingData {
guard let direction = direction else {
preconditionFailure()
let direction: Direction?
/// Returns the encryption key.
///
/// - Precondition: `direction` must be non-nil.
/// - Seealso: `ConfigurationBuilder.tlsWrap`
public var cipherEncryptKey: ZeroingData {
guard let direction = direction else {
preconditionFailure()
}
switch direction {
case .server:
return key(at: 0)
case .client:
return key(at: 2)
}
}
switch direction {
case .server:
return key(at: 0)
case .client:
return key(at: 2)
}
}
/// Returns the decryption key.
///
/// - Precondition: `direction` must be non-nil.
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
public var cipherDecryptKey: ZeroingData {
guard let direction = direction else {
preconditionFailure()
/// Returns the decryption key.
///
/// - Precondition: `direction` must be non-nil.
/// - Seealso: `ConfigurationBuilder.tlsWrap`
public var cipherDecryptKey: ZeroingData {
guard let direction = direction else {
preconditionFailure()
}
switch direction {
case .server:
return key(at: 2)
case .client:
return key(at: 0)
}
}
switch direction {
case .server:
return key(at: 2)
case .client:
return key(at: 0)
/// Returns the HMAC sending key.
///
/// - Seealso: `ConfigurationBuilder.tlsWrap`
public var hmacSendKey: ZeroingData {
guard let direction = direction else {
return key(at: 1)
}
switch direction {
case .server:
return key(at: 1)
case .client:
return key(at: 3)
}
}
}
/// Returns the HMAC sending key.
///
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
public var hmacSendKey: ZeroingData {
guard let direction = direction else {
return key(at: 1)
/// Returns the HMAC receiving key.
///
/// - Seealso: `ConfigurationBuilder.tlsWrap`
public var hmacReceiveKey: ZeroingData {
guard let direction = direction else {
return key(at: 1)
}
switch direction {
case .server:
return key(at: 3)
case .client:
return key(at: 1)
}
}
switch direction {
case .server:
return key(at: 1)
case .client:
return key(at: 3)
/**
Initializes with data and direction.
- Parameter data: The key data.
- Parameter direction: The key direction, or bidirectional if nil. For tls-crypt behavior, must not be nil.
*/
public init(data: Data, direction: Direction?) {
precondition(data.count == StaticKey.contentLength)
secureData = Z(data)
self.direction = direction
}
}
/// Returns the HMAC receiving key.
///
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
public var hmacReceiveKey: ZeroingData {
guard let direction = direction else {
return key(at: 1)
/**
Initializes with file content and direction.
- Parameter file: The text file containing the key.
- Parameter direction: The key direction, or bidirectional if nil.
*/
public convenience init?(file: String, direction: Direction?) {
let lines = file.split(separator: "\n")
self.init(lines: lines, direction: direction)
}
switch direction {
case .server:
return key(at: 3)
case .client:
return key(at: 1)
}
}
/**
Initializes with data and direction.
- Parameter data: The key data.
- Parameter direction: The key direction, or bidirectional if nil. For tls-crypt behavior, must not be nil.
*/
public init(data: Data, direction: Direction?) {
precondition(data.count == StaticKey.contentLength)
secureData = Z(data)
self.direction = direction
}
/**
Initializes with file content and direction.
- Parameter file: The text file containing the key.
- Parameter direction: The key direction, or bidirectional if nil.
*/
public convenience init?(file: String, direction: Direction?) {
let lines = file.split(separator: "\n")
self.init(lines: lines, direction: direction)
}
/// :nodoc:
public convenience init?(lines: [Substring], direction: Direction?) {
var isHead = true
var hexLines: [Substring] = []
/// :nodoc:
public convenience init?(lines: [Substring], direction: Direction?) {
var isHead = true
var hexLines: [Substring] = []
for l in lines {
if isHead {
guard !l.hasPrefix("#") else {
for l in lines {
if isHead {
guard !l.hasPrefix("#") else {
continue
}
guard l == StaticKey.fileHead else {
return nil
}
isHead = false
continue
}
guard l == StaticKey.fileHead else {
guard let first = l.first else {
return nil
}
isHead = false
continue
if first == "-" {
guard l == StaticKey.fileFoot else {
return nil
}
break
}
hexLines.append(l)
}
guard let first = l.first else {
let hex = String(hexLines.joined())
guard hex.count == 2 * StaticKey.contentLength else {
return nil
}
if first == "-" {
guard l == StaticKey.fileFoot else {
return nil
}
break
if let _ = hex.rangeOfCharacter(from: StaticKey.nonHexCharset) {
return nil
}
hexLines.append(l)
let data = Data(hex: hex)
self.init(data: data, direction: direction)
}
let hex = String(hexLines.joined())
guard hex.count == 2 * StaticKey.contentLength else {
return nil
}
if let _ = hex.rangeOfCharacter(from: StaticKey.nonHexCharset) {
return nil
}
let data = Data(hex: hex)
self.init(data: data, direction: direction)
}
/**
Initializes as bidirectional.
- Parameter biData: The key data.
*/
public convenience init(biData data: Data) {
self.init(data: data, direction: nil)
}
private func key(at: Int) -> ZeroingData {
let size = secureData.count / StaticKey.keyCount // 64 bytes each
assert(size == StaticKey.keyLength)
return secureData.withOffset(at * size, count: size)
}
/// :nodoc:
public static func deserialized(_ data: Data) throws -> StaticKey {
return try JSONDecoder().decode(StaticKey.self, from: data)
}
/// :nodoc:
public func serialized() -> Data? {
return try? JSONEncoder().encode(self)
}
// MARK: Codable
/// :nodoc:
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
secureData = Z(try container.decode(Data.self, forKey: .data))
direction = try container.decodeIfPresent(Direction.self, forKey: .dir)
}
/// :nodoc:
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(secureData.toData(), forKey: .data)
try container.encodeIfPresent(direction, forKey: .dir)
/**
Initializes as bidirectional.
- Parameter biData: The key data.
*/
public convenience init(biData data: Data) {
self.init(data: data, direction: nil)
}
private func key(at: Int) -> ZeroingData {
let size = secureData.count / StaticKey.keyCount // 64 bytes each
assert(size == StaticKey.keyLength)
return secureData.withOffset(at * size, count: size)
}
/// :nodoc:
public static func deserialized(_ data: Data) throws -> StaticKey {
return try JSONDecoder().decode(StaticKey.self, from: data)
}
/// :nodoc:
public func serialized() -> Data? {
return try? JSONEncoder().encode(self)
}
// MARK: Codable
/// :nodoc:
public required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
secureData = Z(try container.decode(Data.self, forKey: .data))
direction = try container.decodeIfPresent(Direction.self, forKey: .dir)
}
/// :nodoc:
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(secureData.toData(), forKey: .data)
try container.encodeIfPresent(direction, forKey: .dir)
}
}
}

View File

@ -1,5 +1,5 @@
//
// SessionProxy+TLSWrap.swift
// TLSWrap.swift
// TunnelKit
//
// Created by Davide De Rosa on 9/11/18.
@ -25,7 +25,7 @@
import Foundation
extension SessionProxy {
extension OpenVPN {
/// Holds parameters for TLS wrapping.
public class TLSWrap: Codable {
@ -53,8 +53,8 @@ extension SessionProxy {
}
/// :nodoc:
public static func deserialized(_ data: Data) throws -> SessionProxy.TLSWrap {
return try JSONDecoder().decode(SessionProxy.TLSWrap.self, from: data)
public static func deserialized(_ data: Data) throws -> TLSWrap {
return try JSONDecoder().decode(TLSWrap.self, from: data)
}
/// :nodoc:

View File

@ -57,10 +57,10 @@ class AppExtensionTests: XCTestCase {
let identifier = "com.example.Provider"
let appGroup = "group.com.algoritmico.TunnelKit"
let hostname = "example.com"
let credentials = SessionProxy.Credentials("foo", "bar")
let credentials = OpenVPN.Credentials("foo", "bar")
var sessionBuilder = SessionProxy.ConfigurationBuilder()
sessionBuilder.ca = CryptoContainer(pem: "abcdef")
var sessionBuilder = OpenVPN.ConfigurationBuilder()
sessionBuilder.ca = OpenVPN.CryptoContainer(pem: "abcdef")
sessionBuilder.cipher = .aes128cbc
sessionBuilder.digest = .sha256
sessionBuilder.hostname = hostname

View File

@ -40,14 +40,13 @@ class ConfigurationParserTests: XCTestCase {
// from lines
func testCompression() throws {
// XCTAssertNotNil(try OptionsBundle.parsed(fromLines: ["comp-lzo"]).warning)
XCTAssertNil(try ConfigurationParser.parsed(fromLines: ["comp-lzo"]).warning)
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: ["comp-lzo no"]))
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: ["comp-lzo yes"]))
// XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: ["comp-lzo yes"]))
XCTAssertNil(try OpenVPN.ConfigurationParser.parsed(fromLines: ["comp-lzo"]).warning)
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromLines: ["comp-lzo no"]))
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromLines: ["comp-lzo yes"]))
// XCTAssertThrowsError(try OpenVPN.ConfigurationParser.parsed(fromLines: ["comp-lzo yes"]))
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: ["compress"]))
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: ["compress lzo"]))
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromLines: ["compress"]))
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromLines: ["compress lzo"]))
}
func testDHCPOption() throws {
@ -59,9 +58,9 @@ class ConfigurationParserTests: XCTestCase {
"dhcp-option PROXY_HTTPS 7.8.9.10 8082",
"dhcp-option PROXY_BYPASS foo.com bar.org net.chat"
]
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: lines))
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromLines: lines))
let parsed = try! ConfigurationParser.parsed(fromLines: lines).configuration
let parsed = try! OpenVPN.ConfigurationParser.parsed(fromLines: lines).configuration
XCTAssertEqual(parsed.dnsServers, ["8.8.8.8", "ffff::1"])
XCTAssertEqual(parsed.searchDomain, "example.com")
XCTAssertEqual(parsed.httpProxy?.address, "1.2.3.4")
@ -72,24 +71,24 @@ class ConfigurationParserTests: XCTestCase {
}
func testRedirectGateway() throws {
var parsed: SessionProxy.Configuration
var parsed: OpenVPN.Configuration
parsed = try! ConfigurationParser.parsed(fromLines: []).configuration
parsed = try! OpenVPN.ConfigurationParser.parsed(fromLines: []).configuration
XCTAssertEqual(parsed.routingPolicies, nil)
XCTAssertNotEqual(parsed.routingPolicies, [])
parsed = try! ConfigurationParser.parsed(fromLines: ["redirect-gateway ipv4 block-local"]).configuration
parsed = try! OpenVPN.ConfigurationParser.parsed(fromLines: ["redirect-gateway ipv4 block-local"]).configuration
XCTAssertEqual(Set(parsed.routingPolicies!), Set([.IPv4, .blockLocal]))
}
func testConnectionBlock() throws {
let lines = ["<connection>", "</connection>"]
XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: lines))
XCTAssertThrowsError(try OpenVPN.ConfigurationParser.parsed(fromLines: lines))
}
// from file
func testPIA() throws {
let file = try ConfigurationParser.parsed(fromURL: url(withName: "pia-hungary"))
let file = try OpenVPN.ConfigurationParser.parsed(fromURL: url(withName: "pia-hungary"))
XCTAssertEqual(file.configuration.hostname, "hungary.privateinternetaccess.com")
XCTAssertEqual(file.configuration.cipher, .aes128cbc)
XCTAssertEqual(file.configuration.digest, .sha1)
@ -100,7 +99,7 @@ class ConfigurationParserTests: XCTestCase {
}
func testStripped() throws {
let lines = try ConfigurationParser.parsed(fromURL: url(withName: "pia-hungary"), returnsStripped: true).strippedLines!
let lines = try OpenVPN.ConfigurationParser.parsed(fromURL: url(withName: "pia-hungary"), returnsStripped: true).strippedLines!
let stripped = lines.joined(separator: "\n")
print(stripped)
}
@ -112,8 +111,8 @@ class ConfigurationParserTests: XCTestCase {
private func privateTestEncryptedCertificateKey(pkcs: String) throws {
let cfgURL = url(withName: "tunnelbear.enc.\(pkcs)")
XCTAssertThrowsError(try ConfigurationParser.parsed(fromURL: cfgURL))
XCTAssertNoThrow(try ConfigurationParser.parsed(fromURL: cfgURL, passphrase: "foobar"))
XCTAssertThrowsError(try OpenVPN.ConfigurationParser.parsed(fromURL: cfgURL))
XCTAssertNoThrow(try OpenVPN.ConfigurationParser.parsed(fromURL: cfgURL, passphrase: "foobar"))
}
private func url(withName name: String) -> URL {

View File

@ -49,8 +49,8 @@ class ControlChannelTests: XCTestCase {
// 00 // ack_size
// 00000000 // message packet_id (HARD_RESET -> UInt32(0))
func testHMAC() {
let key = StaticKey(biData: Data(hex: hex))
let server = CryptoBox(cipherAlgorithm: nil, digestAlgorithm: SessionProxy.Digest.sha1.rawValue)
let key = OpenVPN.StaticKey(biData: Data(hex: hex))
let server = CryptoBox(cipherAlgorithm: nil, digestAlgorithm: OpenVPN.Digest.sha1.rawValue)
XCTAssertNoThrow(try server.configure(withCipherEncKey: nil, cipherDecKey: nil, hmacEncKey: key.hmacReceiveKey, hmacDecKey: key.hmacSendKey))
// let original = Data(hex: "38858fe14742fdae40e67c9137933a412a711c0d0514aca6db6476d17d000000015b96c9470000000000")
@ -69,8 +69,8 @@ class ControlChannelTests: XCTestCase {
// 00 // ack_size
// 00000000 // message packet_id
func testAuth() {
let client = try! ControlChannel.AuthSerializer(withKey: StaticKey(data: Data(hex: hex), direction: .client), digest: .sha512)
let server = try! ControlChannel.AuthSerializer(withKey: StaticKey(data: Data(hex: hex), direction: .server), digest: .sha512)
let client = try! OpenVPN.ControlChannel.AuthSerializer(withKey: OpenVPN.StaticKey(data: Data(hex: hex), direction: .client), digest: .sha512)
let server = try! OpenVPN.ControlChannel.AuthSerializer(withKey: OpenVPN.StaticKey(data: Data(hex: hex), direction: .server), digest: .sha512)
// let original = Data(hex: "38bccfd1")
let original = Data(hex: "38bccfd171ce22e085e01a3454c354f3c3093b00fc8d6228a8b69ef503d56f6a572ebd26a800711b4cd4df2b9daf06cb90f82379e7815e39fb73be4ac5461752db4f35120474af82b2000000015b93b65d0000000000")
@ -101,8 +101,8 @@ class ControlChannelTests: XCTestCase {
}
func testCrypt() {
let client = try! ControlChannel.CryptSerializer(withKey: StaticKey(data: Data(hex: hex), direction: .client))
let server = try! ControlChannel.CryptSerializer(withKey: StaticKey(data: Data(hex: hex), direction: .server))
let client = try! OpenVPN.ControlChannel.CryptSerializer(withKey: OpenVPN.StaticKey(data: Data(hex: hex), direction: .client))
let server = try! OpenVPN.ControlChannel.CryptSerializer(withKey: OpenVPN.StaticKey(data: Data(hex: hex), direction: .server))
let original = Data(hex: "407bf3d6a260e6476d000000015ba4155887940856ddb70e01693980c5c955cb5506ecf9fd3e0bcee0c802ec269427d43bf1cda1837ffbf30c83cacff852cd0b7f4c")
let timestamp = UInt32(0x5ba41558)

View File

@ -49,7 +49,7 @@ class DataPathPerformanceTests: XCTestCase {
let ck = try! SecureRandom.safeData(length: 32)
let hk = try! SecureRandom.safeData(length: 32)
let crypto = try! SessionProxy.EncryptionBridge(.aes128cbc, .sha1, ck, ck, hk, hk)
let crypto = try! OpenVPN.EncryptionBridge(.aes128cbc, .sha1, ck, ck, hk, hk)
encrypter = crypto.encrypter()
decrypter = crypto.decrypter()

View File

@ -137,7 +137,7 @@ class EncryptionTests: XCTestCase {
func testCertificatePreamble() {
let url = Bundle(for: EncryptionTests.self).url(forResource: "tunnelbear", withExtension: "crt")!
let cert = CryptoContainer(pem: try! String(contentsOf: url))
let cert = OpenVPN.CryptoContainer(pem: try! String(contentsOf: url))
XCTAssert(cert.pem.hasPrefix("-----BEGIN"))
}

View File

@ -26,7 +26,7 @@
import XCTest
@testable import TunnelKit
private extension SessionReply {
private extension OpenVPN.PushReply {
func debug() {
print("Compression framing: \(options.compressionFraming?.description ?? "disabled")")
print("Compression algorithm: \(options.compressionAlgorithm?.description ?? "disabled")")
@ -48,7 +48,7 @@ class PushTests: XCTestCase {
func testNet30() {
let msg = "PUSH_REPLY,redirect-gateway def1,dhcp-option DNS 209.222.18.222,dhcp-option DNS 209.222.18.218,ping 10,comp-lzo no,route 10.5.10.1,topology net30,ifconfig 10.5.10.6 10.5.10.5,auth-token AUkQf/b3nj3L+CH4RJPP0Vuq8/gpntr7uPqzjQhncig="
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.ipv4?.address, "10.5.10.6")
@ -59,7 +59,7 @@ class PushTests: XCTestCase {
func testSubnet() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0,peer-id 0"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.ipv4?.address, "10.8.0.2")
@ -70,7 +70,7 @@ class PushTests: XCTestCase {
func testRoute() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,route-gateway 10.8.0.1,route 192.168.0.0 255.255.255.0 10.8.0.12,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0,peer-id 0"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
let route = reply.options.ipv4!.routes.first!
@ -82,7 +82,7 @@ class PushTests: XCTestCase {
func testIPv6() {
let msg = "PUSH_REPLY,dhcp-option DNS6 2001:4860:4860::8888,dhcp-option DNS6 2001:4860:4860::8844,tun-ipv6,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig-ipv6 fe80::601:30ff:feb7:ec01/64 fe80::601:30ff:feb7:dc02,ifconfig 10.8.0.2 255.255.255.0,peer-id 0"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.ipv4?.address, "10.8.0.2")
@ -96,7 +96,7 @@ class PushTests: XCTestCase {
func testCompressionFraming() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,comp-lzo no,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-CBC"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compLZO)
@ -104,29 +104,29 @@ class PushTests: XCTestCase {
func testCompression() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-CBC"
var reply: SessionReply
var reply: OpenVPN.PushReply
reply = try! SessionProxy.PushReply(message: msg.appending(",comp-lzo no"))!
reply = try! OpenVPN.PushReply(message: msg.appending(",comp-lzo no"))!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compLZO)
XCTAssertEqual(reply.options.compressionAlgorithm, .disabled)
reply = try! SessionProxy.PushReply(message: msg.appending(",comp-lzo"))!
reply = try! OpenVPN.PushReply(message: msg.appending(",comp-lzo"))!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compLZO)
XCTAssertEqual(reply.options.compressionAlgorithm, .LZO)
reply = try! SessionProxy.PushReply(message: msg.appending(",comp-lzo yes"))!
reply = try! OpenVPN.PushReply(message: msg.appending(",comp-lzo yes"))!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compLZO)
XCTAssertEqual(reply.options.compressionAlgorithm, .LZO)
reply = try! SessionProxy.PushReply(message: msg.appending(",compress"))!
reply = try! OpenVPN.PushReply(message: msg.appending(",compress"))!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compress)
XCTAssertEqual(reply.options.compressionAlgorithm, .disabled)
reply = try! SessionProxy.PushReply(message: msg.appending(",compress lz4"))!
reply = try! OpenVPN.PushReply(message: msg.appending(",compress lz4"))!
reply.debug()
XCTAssertEqual(reply.options.compressionFraming, .compress)
XCTAssertEqual(reply.options.compressionAlgorithm, .other)
@ -134,7 +134,7 @@ class PushTests: XCTestCase {
func testNCP() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,comp-lzo no,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-GCM"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.cipher, .aes256gcm)
@ -142,7 +142,7 @@ class PushTests: XCTestCase {
func testNCPTrailing() {
let msg = "PUSH_REPLY,dhcp-option DNS 8.8.8.8,dhcp-option DNS 4.4.4.4,comp-lzo no,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.18 10.8.0.17,peer-id 3,cipher AES-256-GCM,auth-token"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.cipher, .aes256gcm)
@ -150,7 +150,7 @@ class PushTests: XCTestCase {
func testPing() {
let msg = "PUSH_REPLY,route 192.168.1.0 255.255.255.0,route 10.0.2.0 255.255.255.0,dhcp-option DNS 192.168.1.99,dhcp-option DNS 176.103.130.130,route 10.0.2.1,topology net30,ping 10,ping-restart 60,ifconfig 10.0.2.14 10.0.2.13"
let reply = try! SessionProxy.PushReply(message: msg)!
let reply = try! OpenVPN.PushReply(message: msg)!
reply.debug()
XCTAssertEqual(reply.options.keepAliveInterval, 10)
@ -158,7 +158,7 @@ class PushTests: XCTestCase {
func testProvost() {
let msg = "PUSH_REPLY,route 87.233.192.218,route 87.233.192.219,route 87.233.192.220,route 87.248.186.252,route 92.241.171.245,route 103.246.200.0 255.255.252.0,route 109.239.140.0 255.255.255.0,route 128.199.0.0 255.255.0.0,route 13.125.0.0 255.255.0.0,route 13.230.0.0 255.254.0.0,route 13.56.0.0 255.252.0.0,route 149.154.160.0 255.255.252.0,route 149.154.164.0 255.255.252.0,route 149.154.168.0 255.255.252.0,route 149.154.172.0 255.255.252.0,route 159.122.128.0 255.255.192.0,route 159.203.0.0 255.255.0.0,route 159.65.0.0 255.255.0.0,route 159.89.0.0 255.255.0.0,route 165.227.0.0 255.255.0.0,route 167.99.0.0 255.255.0.0,route 174.138.0.0 255.255.128.0,route 176.67.169.0 255.255.255.0,route 178.239.88.0 255.255.248.0,route 178.63.0.0 255.255.0.0,route 18.130.0.0 255.255.0.0,route 18.144.0.0 255.255.0.0,route 18.184.0.0 255.254.0.0,route 18.194.0.0 255.254.0.0,route 18.196.0.0 255.254.0.0,route 18.204.0.0 255.252.0.0,push-continuation 2"
let reply = try? SessionProxy.PushReply(message: msg)!
let reply = try? OpenVPN.PushReply(message: msg)!
reply?.debug()
}
}

View File

@ -63,7 +63,7 @@ dccdb953cdf32bea03f365760b0ed800
func testFileBidirectional() {
let expected = Data(hex: "cf55d863fcbe314df5f0b45dbe974d9bde33ef5b4803c3985531c6c23ca6906d6cd028efc8585d1b9e71003566bd7891b9cc9212bcba510109922eed87f5c8e6")
let key = StaticKey(file: content, direction: nil)
let key = OpenVPN.StaticKey(file: content, direction: nil)
XCTAssertNotNil(key)
XCTAssertEqual(key?.hmacSendKey.toData(), expected)
@ -73,7 +73,7 @@ dccdb953cdf32bea03f365760b0ed800
func testFileDirection() {
let send = Data(hex: "778a6b35a124e700920879f1d003ba93dccdb953cdf32bea03f365760b0ed8002098d4ce20d045b45a83a8432cc737677aed27125592a7148d25c87fdbe0a3f6")
let receive = Data(hex: "cf55d863fcbe314df5f0b45dbe974d9bde33ef5b4803c3985531c6c23ca6906d6cd028efc8585d1b9e71003566bd7891b9cc9212bcba510109922eed87f5c8e6")
let key = StaticKey(file: content, direction: .client)
let key = OpenVPN.StaticKey(file: content, direction: .client)
XCTAssertNotNil(key)
XCTAssertEqual(key?.hmacSendKey.toData(), send)