This library provides a simplified Swift/Obj-C implementation of the OpenVPN® protocol for the Apple platforms. The crypto layer is built on top of OpenSSL 1.1.0i, which in turn enables support for a certain range of encryption and digest algorithms.
The client is known to work with OpenVPN® 2.3+ servers.
- [x] Handshake and tunneling over UDP or TCP
- [x] Ciphers
- AES-CBC (128/192/256 bit)
- AES-GCM (128/192/256 bit, 2.4)
- [x] HMAC digests
- SHA-2 (224/256/384/512 bit)
- [x] NCP (Negotiable Crypto Parameters, 2.4)
- [x] TLS handshake
- Server validation (CA, EKU)
- Client certificate
- [x] TLS wrapping
- Authentication (
- Encryption (
- Authentication (
- [x] Compression framing
- Compress (2.4)
- LZO (deprecated in 2.4)
- [x] Key renegotiation
- [x] Replay protection (hardcoded window)
The library therefore supports compression framing, just not compression. Remember to match server-side compression framing in order to avoid a confusing loss of data packets. E.g. if server has
comp-lzo no, client must use
compressionFraming = .compLZO.
Support for .ovpn configuration
TunnelKit can parse .ovpn configuration files. Below are a few limitations worth mentioning.
- UDP fragmentation, i.e.
--compressother than empty
- External file references (inline
- Encrypted client certificate keys
- MTU overrides
hostvalues (first wins)
Many other flags are ignored too but it's normally not an issue.
- iOS 11.0+ / macOS 10.11+
- Xcode 10+ (Swift 4.2)
- Git (preinstalled with Xcode Command Line Tools)
- Ruby (preinstalled with macOS)
- CocoaPods 1.4.0
- jazzy (optional, for documentation)
- Disable Bitcode
It's highly recommended to use the Git and Ruby packages provided by Homebrew.
To use with CocoaPods just add this to your Podfile:
Download the library codebase locally:
$ git clone https://github.com/keeshux/tunnelkit.git
Assuming you have a working CocoaPods environment, setting up the library workspace only requires installing the pod dependencies:
$ pod install
After that, open
TunnelKit.xcworkspace in Xcode and run the unit tests found in the
TunnelKitTests target. A simple CMD+U while on
TunnelKit-iOS should do that as well.
There is a
Demo directory containing a simple app for testing the tunnel, called
BasicTunnel. As usual, prepare for CocoaPods:
$ pod install
Demo.xcworkspace and run the
For the VPN to work properly, the
BasicTunnel demo requires:
- App Groups and Keychain Sharing capabilities
- App IDs with Packet Tunnel entitlements
both in the main app and the tunnel extension target.
In order to test connection to your own server, modify the file
Demo/BasicTunnel-[iOS|macOS]/ViewController.swift and make sure to set
ca to the PEM encoded certificate of your VPN server's CA.
private let ca = CryptoContainer(pem: """ -----BEGIN CERTIFICATE----- MIIFJDCC... -----END CERTIFICATE----- """)
The library is split into two modules, in order to decouple the low-level protocol implementation from the platform-specific bridging, namely the NetworkExtension VPN framework.
Full documentation of the public interface is available and can be generated with jazzy. After installing the jazzy Ruby gem with:
$ gem install jazzy
enter the root directory of the repository and run:
The generated output is stored into the
docs directory in HTML format.
Here you will find the low-level entities on top of which the connection is established. Code is mixed Swift and Obj-C, most of it is not exposed to consumers. The Core module depends on OpenSSL and is mostly platform-agnostic.
The entry point is the
SessionProxy class. The networking layer is fully abstract and delegated externally with the use of opaque
The goal of this module is packaging up a black box implementation of a NEPacketTunnelProvider, which is the essential part of a Packet Tunnel Provider app extension. You will find the main implementation in the
This project is licensed under the GPLv3.
As seen in libsignal-protocol-c:
Additional Permissions For Submission to Apple App Store: Provided that you are otherwise in compliance with the GPLv3 for each covered work you convey (including without limitation making the Corresponding Source available in compliance with Section 6 of the GPLv3), the Author also grants you the additional permission to convey through the Apple App Store non-source executable versions of the Program as incorporated into each applicable covered work as Executable Versions only under the Mozilla Public License version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/).
By contributing to this project you are agreeing to the terms stated in the Contributor License Agreement (CLA).
For more details please see CONTRIBUTING.
- PIATunnel - Copyright (c) 2018-Present Private Internet Access
- SwiftyBeaver - Copyright (c) 2015 Sebastian Kreutzberger
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (https://www.openssl.org/)
© 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc.