Categories: Security

Building OpenSSL on Windows

OpenSSL is one of the easier open source projects I have built on Windows. To build it for inclusion with any projects that will be built with Visual C++:

  1. Install Visual Studio 2022 with the “Desktop development with C++” workload.
  2. Install Strawberry Perl for Windows. Ensure perl.exe is added to your PATH environment variable (manually update the PATH if not).
  3. Install NASM and add its path to the PATH environment variable.
  4. Open a Developer Command prompt.
  5. Clone the openssl: TLS/SSL and crypto library GitHub repo (if not yet done).
  6. Change the current directory to the root of the cloned OpenSSL repo then run these commands, substituting your own paths in the first command:
perl Configure VC-WIN64A --prefix=C:/dev/ssl/package-nmake/OpenSSL --openssldir=C:/dev/ssl/package-nmake/SSL

nmake
nmake install

The installation should be in the directory specified by the --openssldir configuration option. The rest of this post is the background experimentation I did to get a local build of the sources.

Native Builds Using MinGW

The instructions for building OpenSSL on Windows have prerequisites like perl and nasm that I didn’t have. Therefore, I decided to start with the instructions for Native builds using MinGW since I already have MSYS2 installed from earlier work Building Octave on Windows. I still wasn’t sure which executable to check for to verify that the compiler is present, so the list of files in the mingw-w64-x86_64-gcc MSYS2 Package was helpful. I launched the MSYS2 MINGW64 shell then run the commands below (see openssl/INSTALL.md)

cd /c/repos/openssl
./Configure
make

The configure command took about 30sec on my desktop and output:

Configuring OpenSSL version 3.2.0-dev for target mingw64
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created Makefile.in
Created Makefile
Created include/openssl/configuration.h

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

The make command took about 21.5 minutes to complete. make test completed in about 27.5 minutes with the report below. I completely ignored the fact that there were failed tests in a build of the cloned sources.

Test Summary Report
-------------------
01-test_symbol_presence.t             (Wstat: 512 (exited 2) Tests: 3 Failed: 2)
  Failed tests:  2-3
  Non-zero exit status: 2
81-test_cmp_cli.t                     (Wstat: 512 (exited 2) Tests: 9 Failed: 2)
  Failed tests:  8-9
  Non-zero exit status: 2
Files=281, Tests=3338, 1652 wallclock secs ( 5.20 usr  1.36 sys + 193.58 cusr 525.59 csys = 725.74 CPU)
Result: FAIL
make[1]: *** [Makefile:3446: run_tests] Error 1
make[1]: Leaving directory '/c/repos/openssl'
make: *** [Makefile:3442: tests] Error 2

Next, I looked into how to create an install of the build. Only the DESTDIR option was needed.

make DESTDIR=/c/dev/ssl/package install

Unfortunately, the build generated was not going to be useful outside MinGW (obvious from looking at the artifacts, but should have been obvious from the outset). Well, it was now time to look into using Visual C++.

Native Builds using Visual C++

I downloaded those pesky prerequisites: Strawberry Perl for Windows and NASM (actually was trivial, compared to the nightmare of installation packages I had anticipated). After installing Strawberry and reopening the command prompt, perl.exe is in the path.

Installing Strawberry Perl for Windows

NASM looked like it has support for the now ancient Visual Studio 2008. It did not update the PATH though so I manually added C:\Program Files\NASM to my user PATH environment variable.

Installing NASM on Windows

I then opened a developer command prompt and ran the build commands:

perl Configure VC-WIN64A

This took about 23 seconds on my desktop and gave similar output to the MSYS configure:

Configuring OpenSSL version 3.2.0-dev for target VC-WIN64A
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created makefile.in
Created makefile
Created include\openssl\configuration.h

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

Kicked off nmake and about 10 minutes later, it ended with these errors, which appear to be a result of conflicts between the Visual C++ and GCC compilers:

   Creating library libcrypto.lib and object libcrypto.exp
libcrypto-shlib-a_time.obj : error LNK2019: unresolved external symbol __imp__timezone referenced in function ossl_asn1_string_to_time_t
libcrypto-shlib-srp_vfy.obj : error LNK2019: unresolved external symbol ___chkstk_ms referenced in function t_fromb64.constprop.0
libcrypto-shlib-ts_rsp_verify.obj : error LNK2001: unresolved external symbol ___chkstk_ms
...
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiGetNameInfo referenced in function addr_strings
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol gai_strerrorA referenced in function addr_strings
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiFreeAddrInfo referenced in function BIO_ADDRINFO_free
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiGetAddrInfo referenced in function BIO_lookup
libcrypto-shlib-bss_log.obj : error LNK2019: unresolved external symbol __mingw_vsprintf referenced in function sprintf.constprop.0
libcrypto-shlib-dso_win32.obj : error LNK2001: unresolved external symbol __mingw_vsprintf
libcrypto-shlib-eng_openssl.obj : error LNK2019: unresolved external symbol __mingw_vfprintf referenced in function fprintf
libcrypto-shlib-ui_openssl.obj : error LNK2001: unresolved external symbol __mingw_vfprintf
libcrypto-shlib-http_lib.obj : error LNK2019: unresolved external symbol __mingw_vsscanf referenced in function sscanf
libcrypto-shlib-v3_utl.obj : error LNK2001: unresolved external symbol __mingw_vsscanf
libcrypto-shlib-cryptlib.obj : error LNK2019: unresolved external symbol __imp__vsnwprintf referenced in function OPENSSL_showfatal
libcrypto-shlib-cryptlib.obj : error LNK2019: unresolved external symbol __imp__vsnprintf referenced in function OPENSSL_showfatal
libcrypto-3-x64.dll : fatal error LNK1120: 11 unresolved externals
NMAKE : fatal error U1077: 'cmd' : return code '0x1'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop. 

Running nmake clean deleted the 2328 .obj files revealed by dir /w /s *.obj – this is where using a separate folder for the build would be helpful.

nmake ran for just under 12 minutes. Since I didn’t use the --prefix and --openssldir options when configuring, I tried to set these environment variables before packaging (as described in the docs).

set PREFIX=C:\dev\ssl\package-nmake\OpenSSL
set OPENSSLDIR=C:\dev\ssl\package-nmake\SSL

nmake install

nmake install failed with a permission denied error, which was unexpected given that I set the environment variables as instructed:

...
        cmd /C ""link" /nologo /debug /dll  /nologo /debug @C:\Users\saint\AppData\Local\Temp\nm6D37.tmp /implib:libssl.lib || (DEL /Q libssl-3-x64.* libssl.lib & EXIT 1)"
LINK : libssl-3-x64.dll not found or not built by the last incremental link; performing full link
   Creating library libssl.lib and object libssl.exp
        IF EXIST libssl-3-x64.dll.manifest  "mt" -nologo -manifest libssl-3-x64.dll.manifest -outputresource:libssl-3-x64.dll
        IF EXIST apps\libssl-3-x64.dll DEL /Q /F apps\libssl-3-x64.dll
        IF EXIST test\libssl-3-x64.dll DEL /Q /F test\libssl-3-x64.dll
        IF EXIST fuzz\libssl-3-x64.dll DEL /Q /F fuzz\libssl-3-x64.dll
        COPY libssl-3-x64.dll apps
        1 file(s) copied.
        COPY libssl-3-x64.dll test
        1 file(s) copied.
        COPY libssl-3-x64.dll fuzz
        1 file(s) copied.
*** Installing runtime libraries
Cannot create directory C:/Program Files/OpenSSL: Permission denied
NMAKE : fatal error U1077: 'C:\software\strawberry\perl\bin\perl.exe' : return code '0x2'
Stop.

Here are the commands that were needed. The install step took about 2 minutes (or about 30 sec if output is redirected to disk).

perl Configure VC-WIN64A --prefix=C:/dev/ssl/package-nmake/OpenSSL --openssldir=C:/dev/ssl/package-nmake/SSL

nmake
nmake install

Outstanding Questions

  1. Why don’t the environment variables work for nmake install?

Article info




Leave a Reply

Your email address will not be published. Required fields are marked *