# Changing openvpn client to use hardware token

## pa4wdh

Hi All,

I'm using openvpn and recently bought four Feitian ePass2003 tokens to use them to store VPN keys.

I've written the privkey,pubkey and certificate to the token, and it looks ok to me:

```

Private Key Object; RSA 

  label:      client

  ID:         9a1ab605a483cb9b60ff4e003002c33258a68a5f

  Usage:      decrypt, sign

  Access:     none

Public Key Object; RSA 2048 bits

  label:      client

  ID:         9a1ab605a483cb9b60ff4e003002c33258a68a5f

  Usage:      encrypt, verify

  Access:     none

Certificate Object; type = X.509 cert

  label:      client

  subject:    DN: CN=client

  ID:         9a1ab605a483cb9b60ff4e003002c33258a68a5f

```

Openvpn also finds it:

```

The following objects are available for use.

Each object shown below may be used as parameter to

--pkcs11-id option please remember to use single quote mark.

Certificate

       DN:             CN=client

       Serial:         02

       Serialized id:  EnterSafe/PKCS\x2315/20de5b608003003c/laptop\x20\x28User\x20PIN\x29/9A1AB605A483CB9B60FF4E003002C33258A68A5F

```

I only changed the relevant statements in the openvpn config:

```

57,58c57,58

<  #cert /home/pa4wdh/home/openvpn.new/client.crt

<  #key /home/pa4wdh/home/openvpn.new/client.key

---

>  cert /home/pa4wdh/home/openvpn.new/client.crt

>  key /home/pa4wdh/home/openvpn.new/client.key

60,63d59

<  pkcs11-providers /usr/lib64/opensc-pkcs11.so

<  pkcs11-id "EnterSafe/PKCS\\x2315/20de5b608003003c/laptop\\x20\\x28User\\x20PIN\\x29/9A1AB605A483CB9B60FF4E003002C33258A68A5F"

<  pkcs11-cert-private 1

```

But now the VPN doesn work anymore  :Sad: 

This is the output i get:

```

Mon Jun  1 10:31:59 2020 OpenVPN 2.4.7 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on May 31 2020

Mon Jun  1 10:31:59 2020 library versions: OpenSSL 1.1.1d  10 Sep 2019, LZO 2.10

Mon Jun  1 10:31:59 2020 PKCS#11: Adding PKCS#11 provider '/usr/lib64/opensc-pkcs11.so'

Mon Jun  1 10:32:10 2020 NOTE: the current --script-security setting may allow this configuration to call user-defined scripts

Enter laptop (User PIN) token Password:

Mon Jun  1 10:32:12 2020 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication

Mon Jun  1 10:32:12 2020 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication

Mon Jun  1 10:32:12 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]192.168.230.1:4500

Mon Jun  1 10:32:12 2020 UDP link local (bound): [AF_INET][undef]:4242

Mon Jun  1 10:32:12 2020 UDP link remote: [AF_INET]192.168.230.1:4500

Mon Jun  1 10:32:12 2020 VERIFY OK: depth=1, CN=Easy-RSA CA

Mon Jun  1 10:32:12 2020 VERIFY KU OK

Mon Jun  1 10:32:12 2020 Validating certificate extended key usage

Mon Jun  1 10:32:12 2020 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication

Mon Jun  1 10:32:12 2020 VERIFY EKU OK

Mon Jun  1 10:32:12 2020 VERIFY OK: depth=0, CN=server

Mon Jun  1 10:32:12 2020 OpenSSL: error:141F0006:SSL routines:tls_construct_cert_verify:EVP lib

Mon Jun  1 10:32:12 2020 TLS_ERROR: BIO read tls_read_plaintext error

Mon Jun  1 10:32:12 2020 TLS Error: TLS object -> incoming plaintext read error

Mon Jun  1 10:32:12 2020 TLS Error: TLS handshake failed

```

There is no special output on the server side.

Any suggestions on how to fix this?

----------

## Banana

Could be this topic here:

https://community.openvpn.net/openvpn/ticket/1216

https://github.com/dpb587/ssoca/issues/13

----------

## pa4wdh

Thanks for the links, it could indeed be related. I've done some testing, and i have to downgrade openvpn to tls1.0 for it to work. It seems like the more recent crypto's used in TLS1.2 and 1.3 are not supported, when the client and server negotiate to such cipher it fails. I'll contact Feitian to see it there is anything i can do about this, otherwise i need other hardware.

----------

## pa4wdh

It seems i might need different hardware. Any suggestions?

I prefer to have a USB key instead of a separate smartcard and reader. Ideal situation would be one that can handle two openvpn simultaneously.

----------

## pa4wdh

I did some more testing, and now i have TLS1.2 running. It turns out that if i use mbedtls for the server side TLS1.2 works. The tokens are slow (tunnel setup takes almost 2 minutes, long enough for the default keepalive settings to kick in  :Smile:  ). But after setting longer keepalive timings it works.

I think openssl does something which fits within the standards but doesn't work well it the tokens. I've seen the same with my ePass2003 tokens as well as a yubikey.

Now i'm trying to get the server side to support the pkcs11 tokens too, so i re-emerged openvpn with the mbedtls and pkcs11 USE flags set, and that fails:

```

checking tap-windows.h presence... no

checking for tap-windows.h... no

checking whether TUNSETPERSIST is declared... yes

checking for setcon in -lselinux... no

checking for pam_start in -lpam... yes

checking for PKCS11_HELPER... yes

checking for mbedtls_ssl_init in -lmbedtls... yes

checking mbedtls version... ok

checking mbedtls pkcs11 support... configure: error: mbedtls has no pkcs11 wrapper compiled in

```

Relevant part of config.log:

```

configure:16786: checking for mbedtls_ssl_init in -lmbedtls

configure:16812: x86_64-pc-linux-gnu-gcc -o conftest -O2 -pipe -march=native -std=c99  -Wl,-O1 -Wl,--as-needed conftest.c -lmbedtls -lpthread -ldl -lcrypto -lpkcs11-helper

                  -lmbedtls -lmbedx509 -lmbedcrypto >&5

configure:16812: $? = 0

configure:16821: result: yes

configure:16834: checking mbedtls version

configure:16854: x86_64-pc-linux-gnu-gcc -c   -O2 -pipe -march=native -std=c99  conftest.c >&5

configure:16854: $? = 0

configure:16855: result: ok

configure:16882: x86_64-pc-linux-gnu-gcc -c   -O2 -pipe -march=native -std=c99  conftest.c >&5

conftest.c: In function 'main':

conftest.c:173:2: error: #error pkcs11 wrapper missing

 #error pkcs11 wrapper missing

  ^~~~~

configure:16882: $? = 1

configure: failed program was:

| /* confdefs.h */

| #define PACKAGE_NAME "OpenVPN"

| #define PACKAGE_TARNAME "openvpn"

| #define PACKAGE_VERSION "2.4.7"

| #define PACKAGE_STRING "OpenVPN 2.4.7"

| #define PACKAGE_BUGREPORT "openvpn-users@lists.sourceforge.net"

| #define PACKAGE_URL ""

| #define OPENVPN_VERSION_RESOURCE 2,4,7,0

| #define OPENVPN_VERSION_MAJOR 2

| #define OPENVPN_VERSION_MINOR 4

| #define OPENVPN_VERSION_PATCH ".7"

| #define PACKAGE "openvpn"

| #define VERSION "2.4.7"

| #define STDC_HEADERS 1

| #define HAVE_SYS_TYPES_H 1

| #define HAVE_SYS_STAT_H 1

| #define HAVE_STDLIB_H 1

| #define HAVE_STRING_H 1

| #define HAVE_MEMORY_H 1

| #define HAVE_STRINGS_H 1

| #define HAVE_INTTYPES_H 1

| #define HAVE_STDINT_H 1

| #define HAVE_UNISTD_H 1

| #define __EXTENSIONS__ 1

| #define _ALL_SOURCE 1

| #define _GNU_SOURCE 1

| #define _POSIX_PTHREAD_SEMANTICS 1

| #define _TANDEM_SOURCE 1

| #define TARGET_ALIAS "x86_64-pc-linux-gnu"

| #define TARGET_LINUX 1

| #define TARGET_PREFIX "L"

| #define IFCONFIG_PATH "/bin/ifconfig"

| #define IPROUTE_PATH "/bin/ip"

| #define ROUTE_PATH "/bin/route"

| #define SYSTEMD_ASK_PASSWORD_PATH ""

| #define HAVE_DLFCN_H 1

| #define LT_OBJDIR ".libs/"

| #define RETSIGTYPE void

| #define HAVE_CPP_VARARG_MACRO_ISO 1

| #define HAVE_CPP_VARARG_MACRO_GCC 1

| #define EMPTY_ARRAY_SIZE 0

| #define SIZEOF_UNSIGNED_INT 4

| #define SIZEOF_UNSIGNED_LONG 8

| #define HAVE_STDIO_H 1

| #define HAVE_STDARG_H 1

| #define HAVE_LIMITS_H 1

| #define HAVE_TIME_H 1

| #define HAVE_ERRNO_H 1

| #define HAVE_FCNTL_H 1

| #define HAVE_CTYPE_H 1

| #define HAVE_SYS_TYPES_H 1

| #define HAVE_SYS_SOCKET_H 1

| #define HAVE_SIGNAL_H 1

| #define HAVE_UNISTD_H 1

| #define HAVE_DLFCN_H 1

| #define HAVE_NETINET_IN_H 1

| #define HAVE_NETINET_IN_SYSTM_H 1

| #define HAVE_NETINET_TCP_H 1

| #define HAVE_ARPA_INET_H 1

| #define HAVE_NETDB_H 1

| #define HAVE_SYS_TIME_H 1

| #define HAVE_SYS_IOCTL_H 1

| #define HAVE_SYS_STAT_H 1

| #define HAVE_SYS_MMAN_H 1

| #define HAVE_SYS_FILE_H 1

| #define HAVE_SYS_WAIT_H 1

| #define HAVE_UNISTD_H 1

| #define HAVE_SIGNAL_H 1

| #define HAVE_LIBGEN_H 1

| #define HAVE_STROPTS_H 1

| #define HAVE_SYSLOG_H 1

| #define HAVE_PWD_H 1

| #define HAVE_GRP_H 1

| #define HAVE_SYS_UIO_H 1

| #define HAVE_LINUX_SOCKIOS_H 1

| #define HAVE_LINUX_TYPES_H 1

| #define HAVE_SYS_POLL_H 1

| #define HAVE_SYS_EPOLL_H 1

| #define HAVE_ERR_H 1

| #define HAVE_NET_IF_H 1

| #define HAVE_NETINET_IP_H 1

| #define HAVE_RESOLV_H 1

| #define HAVE_SYS_UN_H 1

| #define HAVE_IN_ADDR_T 1

| #define HAVE_IN_PORT_T 1

| #define HAVE_IPHDR 1

| #define HAVE_MSGHDR 1

| #define HAVE_CMSGHDR 1

| #define HAVE_IN_PKTINFO 1

| #define HAVE_SA_FAMILY_T 1

| #define HAVE_IPI_SPEC_DST 1

| #define HAVE_DECL_SO_MARK 1

| #define HAVE_ANONYMOUS_UNION_SUPPORT /**/

| #define HAVE_DECL_SIGHUP 1

| #define HAVE_DECL_SIGINT 1

| #define HAVE_DECL_SIGUSR1 1

| #define HAVE_DECL_SIGUSR2 1

| #define HAVE_DECL_SIGTERM 1

| #define HAVE_FORK 1

| #define HAVE_VFORK 1

| #define HAVE_WORKING_VFORK 1

| #define HAVE_WORKING_FORK 1

| #define HAVE_DAEMON 1

| #define HAVE_CHROOT 1

| #define HAVE_GETPWNAM 1

| #define HAVE_SETUID 1

| #define HAVE_NICE 1

| #define HAVE_SYSTEM 1

| #define HAVE_GETPID 1

| #define HAVE_DUP 1

| #define HAVE_DUP2 1

| #define HAVE_GETPASS 1

| #define HAVE_SYSLOG 1

| #define HAVE_OPENLOG 1

| #define HAVE_MLOCKALL 1

| #define HAVE_GETGRNAM 1

| #define HAVE_SETGID 1

| #define HAVE_SETGROUPS 1

| #define HAVE_STAT 1

| #define HAVE_FLOCK 1

| #define HAVE_READV 1

| #define HAVE_WRITEV 1

| #define HAVE_TIME 1

| #define HAVE_GETTIMEOFDAY 1

| #define HAVE_CTIME 1

| #define HAVE_MEMSET 1

| #define HAVE_VSNPRINTF 1

| #define HAVE_STRDUP 1

| #define HAVE_SETSID 1

| #define HAVE_CHDIR 1

| #define HAVE_PUTENV 1

| #define HAVE_GETPEERNAME 1

| #define HAVE_UNLINK 1

| #define HAVE_FTRUNCATE 1

| #define HAVE_EXECVE 1

| #define HAVE_UMASK 1

| #define HAVE_BASENAME 1

| #define HAVE_DIRNAME 1

| #define HAVE_ACCESS 1

| #define HAVE_EPOLL_CREATE 1

| #define HAVE_SENDMSG 1

| #define HAVE_RECVMSG 1

| #define HAVE_INET_NTOP 1

| #define HAVE_INET_PTON 1

| #define HAVE_SOCKET 1

| #define HAVE_RECV 1

| #define HAVE_RECVFROM 1

| #define HAVE_SEND 1

| #define HAVE_SENDTO 1

| #define HAVE_LISTEN 1

| #define HAVE_ACCEPT 1

| #define HAVE_CONNECT 1

| #define HAVE_BIND 1

| #define HAVE_SELECT 1

| #define HAVE_GETHOSTBYNAME 1

| #define HAVE_INET_NTOA 1

| #define HAVE_SETSOCKOPT 1

| #define HAVE_GETSOCKOPT 1

| #define HAVE_GETSOCKNAME 1

| #define HAVE_POLL 1

| #define HAVE_LINUX_IF_TUN_H 1

| #define HAVE_DECL_TUNSETPERSIST 1

| #define ENABLE_FEATURE_TUN_PERSIST 1

| /* end confdefs.h.  */

| 

| #include <mbedtls/config.h>

| 

| int

| main ()

| {

| 

| #ifndef MBEDTLS_PKCS11_C

| #error pkcs11 wrapper missing

| #endif

| 

| 

|   ;

|   return 0;

| }

configure:16887: checking mbedtls pkcs11 support

configure:16894: error: mbedtls has no pkcs11 wrapper compiled in

```

USE flags for openvpn and mbedtls:

```

[ebuild   R    ] net-vpn/openvpn-2.4.7-r1::gentoo  USE="lzo mbedtls pam pkcs11 plugins ssl -down-root -examples -inotify -iproute2 -libressl -lz4 (-selinux) -systemd -test" 0 KiB

[ebuild   R    ] net-libs/mbedtls-2.19.1-r2:0/13::gentoo  USE="threads -doc -havege -libressl -programs -static-libs -test -zlib" ABI_X86="(64) -32 (-x32)" CPU_FLAGS_X86="sse2" 0 KiB

```

It seems something is missing in mbedtls regarding pkcs11 support. I tried the "programs" useflag, but that didn't help.

Any clues?

----------

## Banana

could it be this here: https://github.com/ARMmbed/mbedtls/issues/3006

Also try to emerge dev-libs/libp11, maybe it helps

----------

## pa4wdh

Thanks for the link. I don't hope they will remove pkcs11 support, it make me worry about the future use of pkcs11 tokens.

After some fiddling i got a bit further. I made a custom ebuild for mbedtls with a useflag for pkcs11:

```

# Copyright 1999-2020 Gentoo Authors

# Distributed under the terms of the GNU General Public License v2

EAPI=7

inherit cmake-utils multilib-minimal

DESCRIPTION="Cryptographic library for embedded systems"

HOMEPAGE="https://tls.mbed.org/"

CRYPTO_SUBMODULE="mbedcrypto-2.0.0"

SRC_URI="https://github.com/ARMmbed/mbedtls/archive/${P}.tar.gz

   https://github.com/ARMmbed/mbed-crypto/archive/${CRYPTO_SUBMODULE}.tar.gz"

S=${WORKDIR}/${PN}-${P}

LICENSE="Apache-2.0"

SLOT="0/13" # slot for libmbedtls.so

KEYWORDS="~alpha amd64 arm arm64 ~hppa ia64 ~m68k ~mips ppc ppc64 ~s390 ~sparc x86"

IUSE="cpu_flags_x86_sse2 doc havege libressl pkcs11 programs -static-libs test threads zlib"

RESTRICT="!test? ( test )"

RDEPEND="

   programs? (

      !libressl? ( dev-libs/openssl:0= )

      libressl? ( dev-libs/libressl:0= )

   )

   zlib? ( >=sys-libs/zlib-1.2.8-r1[${MULTILIB_USEDEP}] )"

DEPEND="${RDEPEND}

   doc? ( app-doc/doxygen media-gfx/graphviz )

   test? ( dev-lang/perl )"

enable_mbedtls_option() {

   local myopt="$@"

   # check that config.h syntax is the same at version bump

   sed -i \

      -e "s://#define ${myopt}:#define ${myopt}:" \

      include/mbedtls/config.h || die

}

PATCHES=(

   "${FILESDIR}"/${PN}-dont-overwrite-headers.patch

   "${FILESDIR}"/${PN}-un-pebcak-705038-wrong-file.patch

   "${FILESDIR}"/${PN}-2.19.1-zlib.patch #706112

)

src_prepare() {

   use cpu_flags_x86_sse2 && enable_mbedtls_option MBEDTLS_HAVE_SSE2

   use zlib && enable_mbedtls_option MBEDTLS_ZLIB_SUPPORT

   use havege && enable_mbedtls_option MBEDTLS_HAVEGE_C

   use threads && enable_mbedtls_option MBEDTLS_THREADING_C

   use threads && enable_mbedtls_option MBEDTLS_THREADING_PTHREAD

   use pkcs11 && enable_mbedtls_option MBEDTLS_PKCS11_C

   use pkcs11 && enable_mbedtls_option USE_PKCS11_HELPER_LIBRARY

   # pretend to be git submodule

   rmdir "${S}"/crypto

   mv "${WORKDIR}"/mbed-crypto-${CRYPTO_SUBMODULE} "${S}"/crypto

   cmake-utils_src_prepare

}

multilib_src_configure() {

   local mycmakeargs=(

      -DENABLE_PROGRAMS=$(multilib_native_usex programs)

      -DENABLE_ZLIB_SUPPORT=$(usex zlib)

      -DUSE_STATIC_MBEDTLS_LIBRARY=$(usex static-libs)

      -DENABLE_TESTING=$(usex test)

      -DUSE_SHARED_MBEDTLS_LIBRARY=ON

      -DINSTALL_MBEDTLS_HEADERS=ON

      -DLIB_INSTALL_DIR="/usr/$(get_libdir)"

   )

   cmake-utils_src_configure

}

multilib_src_compile() {

   cmake-utils_src_compile

   use doc && multilib_is_native_abi && emake apidoc

}

multilib_src_test() {

   LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${BUILD_DIR}/library" \

      cmake-utils_src_test

}

multilib_src_install() {

   cmake-utils_src_install

}

multilib_src_install_all() {

   use doc && HTML_DOCS=( apidoc )

   einstalldocs

   if use programs ; then

      # avoid file collisions with sys-apps/coreutils

      local p e

      for p in "${ED}"/usr/bin/* ; do

         if [[ -x "${p}" && ! -d "${p}" ]] ; then

            mv "${p}" "${ED}"/usr/bin/mbedtls_${p##*/} || die

         fi

      done

      for e in aes hash pkey ssl test ; do

         docinto "${e}"

         dodoc programs/"${e}"/*.c

         dodoc programs/"${e}"/*.txt

      done

   fi

}

```

This compiles without problems and after that pkcs11 seems to be enabled at runtime.

The next step is to recompile openvpn with the pkcs11 and mbedtls useflags and that failed. Using pkcs11 in mbedtls requires pkcs11-helper, so i patched configure.ac to add -lpkcs11-helper when it checks the presence of mbedtls, however it still fails. From config.log:

```

configure:16422: checking for PKCS11_HELPER

configure:16429: $PKG_CONFIG --exists --print-errors "libpkcs11-helper-1 >= 1.11"

configure:16432: $? = 0

configure:16446: $PKG_CONFIG --exists --print-errors "libpkcs11-helper-1 >= 1.11"

configure:16449: $? = 0

configure:16489: result: yes

configure:16786: checking for mbedtls_ssl_init in -lmbedtls

configure:16812: x86_64-pc-linux-gnu-gcc -o conftest -O2 -pipe -march=native -std=c99  -Wl,-O1 -Wl,--as-needed conftest.c -lmbedtls -lpthread -ldl -lcrypto -lpkcs11-helper

                  -lmbedtls -lmbedx509 -lmbedcrypto >&5

/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib64/libmbedx509.so: undefined reference to `pkcs11h_certificate_decryptAny'

/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib64/libmbedx509.so: undefined reference to `pkcs11h_certificate_getCertificateBlob'

/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib64/libmbedx509.so: undefined reference to `pkcs11h_certificate_freeCertificate'

/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/../../../../lib64/libmbedx509.so: undefined reference to `pkcs11h_certificate_signAny'

collect2: error: ld returned 1 exit status

```

The -lpkcs11-helper is my modification, and pkcs11h_certificate_signAny is called from mbedtls and provided by pkcs11-helper. Now i'm puzzled about what's missing ...

For anyone who wants to test, this is my user patch for openvpn (installed as /etc/portage/patches/net-vpn/openvpn-2.4.7-r1/pkcs11-helper.patch)

```

diff -Naur openvpn-2.4.7/configure.ac openvpn-2.4.7.mod/configure.ac

--- openvpn-2.4.7/configure.ac   2019-02-18 18:55:36.000000000 +0100

+++ openvpn-2.4.7.mod/configure.ac   2020-06-08 08:56:34.167549250 +0200

@@ -957,7 +957,7 @@

       AC_CHECK_LIB(

          [mbedtls],

          [mbedtls_ssl_init],

-         [MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto"],

+         [MBEDTLS_LIBS="-lmbedtls -lmbedx509 -lmbedcrypto -lpkcs11-helper"],

          [AC_MSG_ERROR([Could not find mbed TLS.])],

          [${PKCS11_HELPER_LIBS}]

       )

```

----------

## pa4wdh

The mbedtls route didn't work out, i couldn't get openvpn+pkcs11+mbedtls  to compile, where especially mbedtls+pkcs11 was the problem.

To check out all the options i also tried openvpn+pkcs11+libressl. This compiles and works but gives the same result as openssl: I have to downgrade to tls1.0 to be able to setup the VPN.

----------

## pa4wdh

I found a working method from an unexpected source.

There is a modified version of openvpn called openvpn-nl. It is basically a patched version of regular openvpn made for the dutch government, see https://openvpn.fox-it.com . I've checked the diffs and mostly they just remove some options which they consider insecure. Besides that the build process has been altered to statically link lzo, mbedtls and pkcs11-helper into openvpn-nl.

A nice side-effect is that mbedtls seem to be a bit more efficient than openssl when it comes to accessing my PKI hardware. Where openssl frequently accesses the hardware, each time taking about 8 seconds, mbedtls does it only once. As a result the tunnel is setup in a matter of seconds instead of minutes, and with tls1.2.

For anyone who's interested i made an ebuild, it changes names everywhere so it can be installed next to regular openvpn. I didn't really care about the dependencies for now, i might update that later.

```

# Copyright 2020 Gentoo Authors

# Distributed under the terms of the GNU General Public License v2

EAPI=7

DESCRIPTION="Modified version of OpenVPN with mbedtls and pkcs11 support"

HOMEPAGE="https://openvpn.fox-it.com"

SRC_URI="https://openvpn.fox-it.com/repos/source/2.4.7-nl1/openvpn-nl-src-2.4.7-nl1.tar.gz"

LICENSE="GPL-2"

SLOT="0"

KEYWORDS="amd64 x86"

IUSE="cpu_flags_x86_aes"

DEPEND=""

RDEPEND="${DEPEND}"

BDEPEND=""

CONFIG_CHECK="~TUN"

src_unpack() {

   unpack ${A}

   mv openvpn-nl openvpn-nl-2.4.7

}

src_prepare() {

   eapply_user

}

src_configure() {

   if use cpu_flags_x86_aes; then

      einfo "Enabling AES-NI support"

      cd ${WORKDIR}/openvpn-nl-2.4.7/mbedtls

      scripts/config.pl set MBEDTLS_AESNI_C

   else

      einfo "Not enabling AES-NI support"

   fi

}

src_compile() {

   cd ${WORKDIR}/openvpn-nl-2.4.7

   ./build-openvpn-nl.sh

}

src_install() {

   newsbin ${WORKDIR}/openvpn-nl-2.4.7/build-openvpn-nl/src/openvpn/openvpn openvpn-nl

   newinitd "${FILESDIR}/openvpn-nl.init" openvpn-nl

   newconfd "${FILESDIR}/openvpn-nl.conf" openvpn-nl

   exeinto /etc/openvpn-nl

   doexe "${FILESDIR}/up.sh"

   doexe "${FILESDIR}/down.sh"

   newman ${WORKDIR}/openvpn-nl-2.4.7/openvpn/doc/openvpn.8 openvpn-nl.8

}

```

----------

## Banana

quite a find. Does somebody else has experience with openvpn-nl?

----------

## pa4wdh

It has been quite some time since i started this topic and in the mean time i have some experience with openvpn-nl which i'd like to share, I converted both of my VPN's to openvpn-nl with PKI tokens.

Pro's:

- It works  :Smile:  and it runs tls1.2, still haven't found a way to do that with openssl

- It seems to be a bit more efficient with my (slow) PKI tokens, so tunnel setup is done within a few seconds (compared to minutes with openssl)

Con's:

- I'm using it in a ramdisk image where size matters and the resulting openvpn-nl executable is a bit large-ish (1.2M) because it carries it's own copy of mbedtls and pkcs-helper

- You have to use one hardware token per openvpn-nl process. In my case that means i need two tokens because i have two different VPN's. One process can still serve multiple clients if you want

- Tunnel encryption/decryption seems to be a bit less efficient than openssl (which i think uses the kernel and possibly it's hardware support) so the throughput it a bit lower. With openvpn+openssl i got 10MByte/s, with openvpn-nl i get 7.7MByte/s. (Hardware is an AMD GX-412TC SOC at 1 GHz)

----------

## Banana

thx for the feedback

----------

