Topic Overview
------------------

1.) Introduction
2.) Prerequisites
3.) Build Machine Setup
4.) Build OpenSSL v1.1.1m
5.) Build LZO v2.10 DLL
6.) Build PKCS11-Helper v1.28 DLL
7.) Build OpenVPN v2.5.4 include files
8.) Build OpenVPN v2.5.4
9.) Build OpenVPN-GUI v11.26 include files
10.) Build OpenVPN-GUI v11.26
11.) Build TAP-Driver v9.9.2
12.) Build NSIS-Installer
13.) OpenVPN configuration file changes for Windows XP
14.) Test if OpenVPN is working correctly
15.) OpenVPN v2.5.4 Windows XP SP3 bug
16.) Version and download link


1.) Introduction
-------------------

OpenVPN v2.3.18 was the last version that officially supports Windows XP and Windows Server 2003. We lately had the need to use the newer version 2.5.4 of OpenVPN to support stronger data ciphers like AES-256-CBC. Therefore we decided to rebuild the whole package from the ground up to make it compatible with Windows XP and Windows Server 2003. The following article describes in detail how you can rebuild OpenVPN v2.5.4 for use on these older operating systems. The build process was a long journey, because it seems that all official build instructions are partly useless and lead to a dead end most of the time. For example the official instructions state that OpenVPN for Windows is cross compiled on Linux, which is not true at all. We checked the binary and can say for sure that it is a native Windows Visual Studio build!

The benefits of this new version include:
If you don't care about the build steps simply install OpenVPN v2.5.4 on Windows XP and Windows Server 2003 by running the installer package "OpenVPN-v2.5.4.exe" in the root of this archive.

Important: The following steps to build OpenVPN can be done completely in offline mode. You do not need an internet connection at all.




2.) Prerequisites
--------------------

We included all prerequisite packages in the download archive with the exception of the operating system, compiler suite and an unpacker for 7-Zip archives. We used the following listed packages to build the dependencies.

OpenSSL v1.1.1m
LZO v2.10 DLL
PKCS11-Helper v1.28 DLL
OpenVPN v2.5.4 include files
OpenVPN v2.5.4
OpenVPN-GUI v11.26 include files
OpenVPN-GUI v11.26
TAP-Driver v9.9.2
NSIS-Installer for OpenVPN v2.5.4

3.) Build Machine Setup
---------------------------

We need two machines for building OpenVPN v2.5.4. The first one with "Windows XP SP3 x86" or "Windows Server 2003 R2 SP2 x86" and "Windows Driver Development Kit v7.1.0 (7600.16385.1)", the second one with "Windows 10 x64 Build 21H2" and "Visual Studio Enterprise 2019 Version 16.0.1". On both machines we need an unpacker for 7-Zip archives.

Packages build on first machine Packages build on second machine Install Visual Studio 2019 on the second machine with the following workloads:

4.) Build OpenSSL v1.1.1m
------------------------------

REM change directory to root of drive C:
cd C:\

REM install DMAKE Perl package
ppm install dmake-4.11.20080107.ppd

REM run VS2019 x86 command line and set correct variables
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"

REM add NASM assembler to path variable
set "PATH=C:\Program Files (x86)\NASM;%PATH%"

REM change current directory to OpenSSL source code directory
cd C:\openssl-v1.1.1m

REM We have to use the configure parameter "-D_WIN32_WINNT=0x0501" for Windows XP and Windows
REM Server 2003.
perl Configure VC-WIN32 -D_WIN32_WINNT=0x0501 --prefix=C:\openssl-v1.1.1m-shared

REM starts the build process and compiles all OpenSSL libraries and files
nmake

REM tests the inner workings of the OpenSSL libraries, this should be run mandatory to be sure
REM that everything works as designed later on
nmake test

REM After this command the installation can be found in the directory "C:\Program Files\OpenSSL".
nmake install

After these steps the OpenSSL files will be present in the directory which you specified with the "--prefix" parameter for the perl Configure command. In our case the shared release DLLs of OpenSSL are present in the directory "C:\openssl-v1.1.1m-shared". The include files we need are placed in "C:\openssl-v1.1.1m-shared\include\openssl". The library files we need are placed in "C:\openssl-v1.1.1m-shared\lib". We packed the complete directory into the included archive named "OpenSSL_v1.1.1m\openssl-v1.1.1m-shared.7z".


5.) Build LZO v2.10 DLL
--------------------------

REM run VS2019 x86 command line and set correct variables
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
  
REM change current directory to LZO source code directory
cd C:\lzo-2.10
  
REM This will build the shared DLLs.
B\win32\vc_dll.bat
We packed the complete directory into the included archive named "LZO_v2.10\lzo-2.10-shared-DLL.7z".


6.) Build PKCS11-Helper v1.28 DLL
--------------------------------------

REM run VS2019 x86 command line and set correct variables
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
  
REM change current directory to PKCS11-Helper source code directory
cd C:\pkcs11-helper-1.28.0\lib
  
REM starts the build process and compiles the PKCS11-Helper library
nmake -f Makefile.w32-vc OPENSSL=1 OPENSSL_HOME=C:\openssl-v1.1.1m-shared
We packed the complete directory into the included archive named "PKCS11-Helper_v1.28.0\pkcs11-helper-1.28.0-shared-DLL.7z". The DLL we use is located at "PKCS11-Helper_v1.28.0\pkcs11-helper-1.28.0-shared-DLL.7z\lib\libpkcs11-helper-1.dll".


7.) Build OpenVPN v2.5.4 include files
-----------------------------------------

The include file config-msvc-version.h is auto generated by the Visual Studio solution of OpenVPN. The standard OpenVPN source code does not include this file, which is absolutely necessary to build OpenVPN. In the following steps we describe how to generate the include file config-msvc-version.h. The generated include file by this procedure is already present in the directory "OpenVPN_v2.5.4".
REM change current directory to OpenVPN msvc-generate source code directory
cd C:\openvpn-2.5.4\build\msvc\msvc-generate

REM run the java script file with parameters
cscript //Nologo msvc-generate.js --config="C:\openvpn-2.5.4\version.m4" --input="C:\openvpn-2.5.4\config-msvc-version.h.in" --output="C:\openvpn-2.5.4\config-msvc-version.h"
After these steps the resulting file is located at "C:\openvpn-2.5.4\config-msvc-version.h".

Pay attention: This file does contain errors! It seems the PRODUCT_VERSION_PATCH has a wrong value of ".4" instead of simply "4". Therefore also the PACKAGE_VERSION and PRODUCT_VERSION are wrong and have both the value "2.5..4". This error is triggered by the file "C:\openvpn-2.5.4\version.m4" which has the following define:
define([PRODUCT_VERSION_PATCH], [.4])
If we correct this line and remove the point, we get another error in the config-msvc-version.h file. After this change the PACKAGE_STRING is "OpenVPN 2.54", which is missing a point, but both the PACKAGE_VERSION and PRODUCT_VERSION are correct. We already corrected these errors manually in the included file "OpenVPN_v2.5.4\config-msvc-version.h".

The file tap-windows.h is copied from the archive "OpenVPN_v2.5.4\tap-windows-master_for_XP.7z\src\tap-windows.h". The file versionhelpers.h is copied from the Windows 10 SDK version 10.0.17763.0 which comes with Visual Studio 2019. We slightly modified it to make it work without additional include files like winapifamily.h. The original file is located at "C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\VersionHelpers.h" after Visual Studio 2019 is installed.


8.) Build OpenVPN v2.5.4
----------------------------

We can now compile the debug and release configuration for Windows XP without any errors or warnings. The final source code package is located at "OpenVPN_v2.5.4\openvpn_v2.5.4_20220123_for_XP.7z".


9.) Build OpenVPN-GUI v11.26 include files
----------------------------------------------

The include file config.h is auto generated on Linux platforms. The standard OpenVPN-GUI source code does not include this file, which is absolutely necessary to build the OpenVPN-GUI. In the following steps we describe how to generate the include file config.h. The generated include file by this procedure is already present in the directory "OpenVPN-GUI_v11.26".
pacman -S autoconf automake libtool make mingw-w64-i686 mingw-w64-i686-toolchain mingw-w64-x86_64 mingw-w64-x86_64-toolchain nasm pkg-config
cd openvpn-gui
autoreconf -i -v
./configure --prefix=/ --host=i686-w64-mingw32 --build=i686-pc-mingw32 --program-prefix='' OPENSSL_CRYPTO_CFLAGS="-I /home/UserName/openssl-v1.1.1m/include/" OPENSSL_CRYPTO_LIBS="-L /home/UserName/openssl-v1.1.1m/lib/ -lcrypto"
It does not matter if the OpenSSL directory is present or not for the configure command. After this configure command the file "C:\msys32\home\UserName\openvpn-gui\config.h" is created. If we only want to build the OpenVPN-GUI on Visual Studio 2019 we can stop here. It is recommended to stop here an not try to build the OpenVPN-GUI with MSYS2, because even if we would manage to get a working executable this is at least double the size of the Windows executable build with Visual Studio 2019.

The file versionhelpers.h is copied from the Windows 10 SDK version 10.0.17763.0 which comes with Visual Studio 2019. We slightly modified it to make it work without additional include files like winapifamily.h. The original file is located at "C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\VersionHelpers.h" after Visual Studio 2019 is installed.


10.) Build OpenVPN-GUI v11.26
----------------------------------

We can now compile the debug and release configuration for Windows XP without any errors or warnings. The final source code package is located at "OpenVPN-GUI_v11.26\openvpn-gui_v11.26_20220123_for_XP.7z".


11.) Build TAP-Driver v9.9.2
-----------------------------

We have to rebuild the TAP-Driver for Windows XP, because the original driver of OpenVPN v2.3.18 does only support a speed of 10 MBit/s. This limits our connection dramatically. Therefore we implemented a patch to support 1 GBit/s, although the theoretical VPN limit would be around 250 to 300 MBit/s. The final source code package is located at "TAP-Driver_v9.9.2\tap_v9.9.2_20220123_for_XP.7z".


12.) Build NSIS-Installer
---------------------------

The newly created OpenVPN installer is located at "C:\nsis\OpenVPN-v2.5.4.exe". The final source code package is located at "NSIS-Installer\NSIS_Installer_Package_20220123_for_XP.7z".


13.) OpenVPN configuration file changes for Windows XP
------------------------------------------------------------

We should change the following 3 parameters in the OpenVPN configuration file for Windows XP: The parameter "block-outside-dns" is used to block DNS traffic and remove a potential DNS leak. If this parameter is commented out in your VPN configuration file you should enable it.

To completely disable IPv6 routing we should comment out the parameter "route-ipv6 ::/0". Otherwise we see the following error message:
ERROR: Windows route add ipv6 command failed: returned error code 1
We also should enable the additional parameter "auth-nocache". This disables password caching in memory. Without this parameter we see the following error message in the log:
WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
A correct example configuration file section will look like follows:
block-outside-dns
#route-ipv6 ::/0
auth-nocache

14.) Test if OpenVPN is working correctly
--------------------------------------------

To test the correct working of OpenVPN we can use the following 3 internet sites: To disable a potential WebRTC leak in your browser do the following steps based on your browser:

15.) OpenVPN v2.5.4 Windows XP SP3 bug
--------------------------------------------

OpenVPN v2.5.4 contains a severe bug on Windows XP SP3. If we try to connect to the VPN server, we see the following buffer size error in the log file:
2022-01-09 14:24:02 open_tun
2022-01-09 14:24:02 MANAGEMENT: Client disconnected
2022-01-09 14:24:02 fatal buffer size error, size=2089877947
2022-01-09 14:24:02 Exiting due to fatal error
The buffer size of 2089877947 can change randomly. This error is caused by the source code file "tun.c" and the function "get_device_instance_id_interface". The call to CM_Get_Device_Interface_List_Size returns CR_SUCCESS and a random interface list size, which is invalid and based on the value of the variable dev_interface_list_size on function entry. That is the reason why the following call to alloc_buf_gc fails, because the specified buffer size is too big. To solve this problem we have to simply change code line 3672 from
ULONG dev_interface_list_size;
to
ULONG dev_interface_list_size = 0;
This initializes the device interface list size with zero and the returned list size is 1 on Windows XP SP3 for an empty list. The error does not occur on Windows Server 2003 R2 SP2, where a valid list size is returned without any problems.


16.) Version and download link
----------------------------------

The complete OpenVPN package with all necessary files can be downloaded from Sourceforge.

Thanks for your attention and interest in this topic.
Greets Kai Schtrom

Version 1.0 January 23, 2022