Why would I want to compile OpenSSL myself?
OpenSSL is a popular library used for performing various actions around SSL/TLS such as generating keypairs, creating CSRs, and testing connectivity against endpoints encrypted via SSL/TLS. While alternatives such as BoringSSL and LibreSSL do exist, OpenSSL is ubiquitous in the enterprise. OpenSSL comes pre-packed with most Linux distributions, and most of the time, assuming your system is up to date, using the pre-packaged version from your trusted package manager is absolutely fine. On Windows systems, the answer is not so clear-cut. Many independent parties offer a pre-compiled and packaged version of OpenSSL for Windows, but this requires a certain amount of trust in those third parties which personally makes me uncomfortable. Imagine if the C source were to be modified to send any generated private keys to an attacker on the internet!
Beyond the threat of bad actors, there are a myriad of reasons why compiling OpenSSL yourself might be advantageous. Perhaps you need a specific version for security research that is no longer made available for good reason. Perhaps you are developing a product on the bleeding edge and need to take advantage of a branch of OpenSSL which is not yet stable. Whatever the reason, we have you covered.
- State of Compilers
- Compiling OpenSSL for Linux on Ubuntu 20
- Cross Compiling OpenSSL for Windows on Ubuntu 20
- Conclusion
State of Compilers
There are many compilers available for C on both Windows and Linux. In theory it is possible to compile OpenSSL for Windows directly on a windows machine using either Borland or Visual Studio. On Linux, GCC is the most common choice, but there is no reason you couldn’t use a compiler such as clang. However, it is the aim of this guide to produce an OpenSSL binary for both Linux and Windows with as little friction as possible. Therefore, we will be using Ubuntu 20.04 to compile OpenSSL natively with GCC, as well as to cross-compile OpenSSL for Windows via mingw-w64.
Compiling OpenSSL for Linux on Ubuntu 20.04
Start by making sure everything is up to date:
apt-get update
Now, let’s install some dependencies needed to build OpenSSL for Linux.
apt-get install build-essential checkinstall zlib1g-dev -y
We need to install Git so that we can pull down the source for OpenSSL
apt-get install git
I like to uninstall the system packaged version of OpenSSL on my build machine to avoid any confusion.
Apt-get remove openssl
Next, let’s CD to our home directory.
cd openssl
In addition to the more advanced .configure script provided with the source, OpenSSL’s source directory includes a friendlier .config script with common defaults. Make this script executable and run it.
Chmod +x ./config
./config
Now, we can issue make.
Make
This will take several minutes to complete. Assuming it finishes successfully, issue make install
Make install
This will place a binary named openssl in /usr/local/bin/
Issue Ldconfig in order to rebuild the search path for libraries we've added to our installation
ldconfig
Now, let’s make sure OpenSSL works correctly:
cd /usr/local/bin/
Check openssl version:
./openssl version
Notice in the above that the “version” command against the binary functions, outputting the specific revision (j). This indicates that our build was successful.
Cross Compiling OpenSSL for Windows on Ubuntu 20.04
Start by making sure everything is up to date:
apt-get update
Now, let’s install some dependencies needed to build OpenSSL for Linux:
apt-get install build-essential checkinstall zlib1g-dev -y
We need to install Git so that we can pull down the source for OpenSSL
apt-get install git
We have an additional for the compilation dependency, mingw-64:
sudo apt-get install mingw-w64
We will also need zip in order to zip up our binary for transporting to the windows system which it will ultimately live:
apt-get install zip
I like to uninstall the system packaged version of OpenSSL on my build machine to avoid any confusion:
apt-get remove openssl
Next, let’s CD to our home directory:
cd ~
Issue the following to clone the source for OpenSSL 1.1.1, the latest stable branch at this time, into a directory under our home directory named openssl:
git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl.git
Since cross compilation is a little more advanced than what .config offers, we will use the .configure script with some very specific parameters indicating our desire for cross-compilation:
chmod +x ./configure
./Configure --cross-compile-prefix=x86_64-w64-mingw32- mingw64
Like before, we will issue make. This will take several minutes. :
Make
Finally, we will issue make install:
Make install
Perhaps somewhat unintuitively, a folder named C: will have been created in your openssl source directory containing artifacts that represent an overlay for a windows installation:
Notice that inside of C:\’program files’ we have two folders, “Common Files” and “OpenSSL”
Inside of OpenSSL/bin we will find openssl.exe, an executable which will run on a Windows System:
Navigate back to your openssl folder:
cd ~/openssl
And zip up the C: folder containing your build artifacts:
zip -r openssl.zip C:
Using winscp, or whatever method you prefer, bring openssl.zip to your local windows machine.
If you unzip the folder and place the contents of the “Program Files” directory into the “C:\Program Files: files directory on your machine, you will be able to use the OpenSSL executable.
Unzip the folder, and run openssl version:
As you can see, the cross compilation resulted in a fully functional version of OpenSSL for your windows machine.
Conclusion
While it is not always necessary to compile OpenSSL from source in every environment, there are security benefits to doing so. Additionally, as you can see from the above, the procedure is neither especially complex nor time consuming. It is worthwhile for everyone administrator to become familiar with compiling tools from source, whether or not it is something you will commonly have to do – you never know when it will come in handy!