# Plugins implementing TLS Crypt V2 for OpenVPN

## Description

This repository contains plugin implementations of the OpenVPN tls-crypt-v2 mechanism. Each plugin uses a different hardware technology. To use any of the plugins, it is required to use a custom OpenVPN version to add a plugin hook for performing TLS Crypt V2 operations.

## Dependencies

Runtime:

* PKCS11: openssl, a PKCS#11 library
* YubiKey: openssl, yubico-c, yubikey
* JavaCard: pcsclite
* OpenVPN: See openvpn_patched/INSTALL

Build:

* PKCS11: cmake
* YubiKey: cmake, json-c
* JavaCard: cmake, ant
* OpenVPN: See openvpn_patched/INSTALL

## Usage

Add the plugin to your server config and add arguments depending on the plugin. Order of arguments matters!

* SoftHSM: Path to SoftHSM2 Library (e.g. /usr/lib/pkcs11/libsofthsm2.so) and User Pin
* YubiKey: Slot number to use on the YubiKey (e.g. 1, 2 or 3) and access code for the YubiKey (if not set: 0)
* Smartcard: No arguments required

## Build

First, download all git submodules with

```sh
git submodule update --init
```

### Custom OpenVPN

OpenVPN needs to be configured before any plugins can be compiled, since OpenVPN first needs to generate the actual plugin header file

```sh
cd openvpn_patched
autoreconf -i -v -f
./configure
make
```

### PKCS#11 plugin

```sh
cd PKCS11KeyWrappingLibrary
mkdir build && cd build
cmake ..
cmake --build . --target PKCS11KeyWrappingLibrary
```

### YubiKey plugin

```sh
cd YubikeyKeyDerivationLibrary
mkdir build && cd build
cmake ..
cmake --build . --target YubikeyKeyManagementLib
```

### JavaCard plugin

Build JavaCard Applet. Requires setting JAVA_HOME environmental variable to the path of Java 8. Java 8 path is something like `/usr/lib/jvm/java-8-openjdk/`.

```sh
cd SmartcardKeyWrapping/Applet/
export JAVA_HOME=<java-8-path>
# Build Applet
ant build
# Install Applet onto a card, which requires a smart card to be inserted into the computer
ant install 
# If test desired
ant test
```

Build JavaCard plugin with:

```sh
cd SmartcardKeyWrapping/Library/
mkdir build && cd build
cmake ..
cmake --build . --target SmartcardKeyWrappingLibrary
```

## Test

### Key Generation

#### PKCS#11

A sample config using SoftHSM is provided. To test it first build OpenVPN and the PKCS#11 Plugin. Testing requires installing SoftHSM2 and setting up a new token, with `softhsm2-util --init-token --slot 0 --label <name> --pin <user-pin> --so-pin <so-pin>`. If a different PKCS#11 library is used the provided configuration needs to be changed. First, generate server and client keys:

```sh
cd TestEnvironment/Server_openvpn/
./openvpn --genkey tls-crypt-v2-server --plugin ./plugins/libPKCS11KeyWrappingLibrary.so "/usr/lib/pkcs11/libsofthsm2.so" <user-pin>
./openvpn --genkey tls-crypt-v2-client ../Client_openvpn/secrets/softhsm_client.key --plugin ./plugins/libPKCS11KeyWrappingLibrary.so "/usr/lib/pkcs11/libsofthsm2.so" <user-pin>
```

#### YubiKey

Testing changes the config of the YubiKey. Beware of data loss! Slot can either be 1,2 or 3. With 3 both slots are used for increased security. Provided runtime configuration uses both slots, so change if necessary.

```sh
cd TestEnvironment/Server_openvpn/
# Generate Server Key; <slot> sets the slot which should be configured, usually 2. Removes whatever is stored in the slot. <acc_code> is usually 0
./openvpn --genkey tls-crypt-v2-server --plugin ./plugins/libYubikeyKeyManagementLib.so <slot> <acc_code>
# Generate Client Key
./openvpn --genkey tls-crypt-v2-client ../Client_openvpn/secrets/yubikey_client.key --plugin ./plugins/libYubikeyKeyManagementLib.so <slot> <acc_code>
```

#### JavaCard

```sh
cd TestEnvironment/Server_openvpn/
# Generate Server Key
./openvpn --genkey tls-crypt-v2-server --plugin ./plugins/libSmartcardKeyWrappingLibrary.so
# Generate Client Key
./openvpn --genkey tls-crypt-v2-client ../Client_openvpn/secrets/smartcard_client.key --plugin ./plugins/libSmartcardKeyWrappingLibrary.so
```

### Runtime Test

Run the server from `TestEnvironment/Server_openvpn/` with:

```sh
sudo ./openvpn --config configs/<plugin-server-conf>
```

Options for `plugin-server-conf` are `yubikey_server.conf`, `softhsm_server.conf`, `smartcard_server.conf`
Then run the client from `TestEnvironment/Client_openvpn/` with:

```sh
sudo ./openvpn --config configs/<plugin-client-conf>
```

Options for `plugin-client-conf` are `yubikey_client.conf`, `softhsm_client.conf`, `smartcard_client.conf`

## Import existing server key file

The smart card plugin can be used as a drop-in replacement for an existing server configuration. This is not possible for the YubiKey and PKCS#11 plugins. With both the YubiKey and the smart card plugin the server key file created when generating a server key can be reimported (for example to restore the backup key). To import a key file, use the ImportKey utility. The tool is built with CMake and requires OpenSSL.

Usage:
```bash
./ImportKeyFile <key_file_path> <plugin_path> [plugin_specific_arguments]
```

## License
I release the project under the GNU General Public License v2.0. The plugin base is the openvpn_defer_auth from Mozilla.