Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static OpenSSL *.a libraries not linked target binary (using Statically Compiled Qt with SSL)

Tags:

c++

ssl

openssl

qt

Right off the bat, sorry about the length of the question, but it is due to all the additional details I am providing which I hope could help trouble shoot the issue faster

What am I trying to achieve?

I need to create a portable (all-in-one) application, with SSL support.

What is the problem?

So the core problem I am facing is getting SSL support included into my binary/portable app.

A MCVE of the app is simple:

Project .pro file

QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

Project main.cpp

#include <QCoreApplication>
#include <QSslSocket>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "Is SSL Enabled? " << QSslSocket::supportsSsl();
    qDebug() << "SSL Library Build Version (Qt compiled against): " << QSslSocket::sslLibraryBuildVersionString();
    qDebug() << "SSL Library Version String (available locally): " << QSslSocket::sslLibraryVersionString();

    return a.exec();
}

  • Output on my DEV machine:

    Is SSL Enabled?  true
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  "OpenSSL 1.1.1d  10 Sep 2019"

Info of Dev Machine

    C:\Users\cybex>echo %PATH%
    C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin

    C:\Users\cybex>openssl
    WARNING: can't open config file: /z/extlib/_openssl_/ssl/openssl.cnf
    OpenSSL> version
    OpenSSL 1.0.2g  1 Mar 2016

  • Running the same binary on a fresh Windows 10 x86 machine results in:

    Is SSL Enabled?  false
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  ""

Info of Test Machine (Completely fresh install - Windows 10 x86)

    C:\Users\cybex>echo %PATH%
    C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
    C:\Users\cybex>openssl
    'openssl' is not recognized as an internal or external command,
    operable program or batch file.

  • Running the same binary on a fresh Windows 7 x64 machine results in:

    Is SSL Enabled?  false
    SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
    SSL Library Version String (available locally):  ""

Info of Test Machine (Windows 7 x64 laptop with drivers installed)

    C:\Users\Home>echo %PATH%
    C:\Program Files (x86)\OpenSSL\libs;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files (x86)\OpenSSL\libs;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\
    C:\Users\Home>openssl
    'openssl' is not recognized as an internal or external command, operable program or batch file.

By look at the above results, I conclude that installing OpenSSL solves the problem. Good, but I want need to have it included in my portable app.

In achieving this, I am required to

  1. Compile Qt statically with OpenSSL support

I have done this with the help of this script adapted from ps1 powershell script found here on Qt's wiki. I made additions for:

  • OpenSSL home $OPENSSL_HOME

  • number of threads $threads, and

  • architecture type $arch to be used.

Qt Compiling Details & OpenSSL info

  • Compiler: mingw32 located in C:\Qt\Qt5.13.1\Tools\mingw730_32\bin

  • mkspec: win32-g++ (if that makes any difference).

  • OpenSSL version (32 bit): 1.1.1d

The configuration is as follows:

cmd /C "configure.bat -static -debug-and-release -platform win32-g++ -prefix $QtDir `
        -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -opengl desktop -sql-sqlite -ssl -openssl -I $($OPENSSL_HOME)\include -L$($OPENSSL_HOME)\lib\MinGW`
        -opensource -confirm-license `
        -make libs -nomake tools -nomake examples -nomake tests -v"
cmd /C "mingw32-make -k -j$($threads)"

Note 1:

I am using -openssl and not -openssl-linked. I have tried several variations of builing Qt with both -openssl and -openssl-linked. -openssl-linked could never successfully build, see this post I made as to the reason why.

Note 2:

The only successful static Qt compilation I had working was with -ssl -openssl configuration flags enabled

OpenSSL installation (on DEV machine only) is at

`$OPENSSL_HOME = "C:\OpenSSL-Win32"` 

where I am using the statically compiled MinGW libraries for OpenSSL, found in

`$OPENSSL_HOME = "C:\OpenSSL-Win32\lib\MinGW",`

The file contents of C:\OpenSSL-Win32\lib\MinGW is:

Directory: C:\OpenSSL-Win32\lib\MinGW

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2019/09/11     18:11        3347286 libcrypto.a
-a----       2019/09/11     18:10         109020 libcrypto.def
-a----       2019/09/11     18:11         385126 libssl.a
-a----       2019/09/11     18:10          14033 libssl.def
  1. Add link project .pro to OpenSSL libraries

I added the OpenSSL libraries to the .pro file using 2 methods(libraries are the statically compiled MinGW OpenSSL libraries found at C:\OpenSSL-Win32\lib\MinGW)

Manual Entry of libraries into .pro file

QT -= gui
QT += network

# OpenSSL static .a libraries
INCLUDEPATH += "C:\OpenSSL-Win32\include"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libssl.a"
LIBS += -L"C:\OpenSSL-Win32\lib\MinGW\libcrypto.a"

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

Note 3

The binary size with and without the linked libraries above remains the same size

The LDD output of the binary (on my dev machine) with libraries added above is:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

The LDD output of the binary (on my Windows 10 x86 test machine) with libraries added above is:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\Desktop\SSL-Test.exe
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

Qt Library Import into .pro file

Import using (External Library > Import .a file> Static & Windows only options with no debug suffix)

QT -= gui
QT += network

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp

INSTALLS += target

win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lssl

INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW

win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ssl.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libssl.a

win32: LIBS += -L$$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/ -lcrypto

INCLUDEPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW
DEPENDPATH += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW

win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/crypto.lib
else:win32-g++: PRE_TARGETDEPS += $$PWD/../../../../OpenSSL/OpenSSL-Win32/lib/MinGW/libcrypto.a

Using the automatic binary import, the LDD output of the binary (on my dev machine) with libraries added above is:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\QtProjects\build-SSL-Test-Desktop_Qt_Op...
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

And using the automatic library import, the LDD output of the binary (on my Windows 10 x86 test machine) with libraries added above is:

Start-Process -PassThru .\SSL-Test.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
      6280 SSL-Test.exe                                       C:\Users\cybex\Desktop\SSL-Test.exe
      1512 ntdll.dll                                          C:\Windows\SYSTEM32\ntdll.dll
       596 KERNEL32.DLL                                       C:\Windows\system32\KERNEL32.DLL
      1500 KERNELBASE.dll                                     C:\Windows\system32\KERNELBASE.dll

The application output for the dev machine is SSL enabled as mentioned previously in my post (for both manual and automatic library entry):

Is SSL Enabled?  true
SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
SSL Library Version String (available locally):  "OpenSSL 1.1.1d  10 Sep 2019"

The application output for the test machines (w/o OpenSSL installed) is the same as previously too (for both manual and automatic library entry):

Is SSL Enabled?  false
SSL Library Build Version (Qt compiled against):  "OpenSSL 1.1.1d  10 Sep 2019"
SSL Library Version String (available locally):  ""

So with OpenSSL library not being present, it causes the below error when requesting a SSL connection on Non-Dev (fresh / client) machines:

QSslSocket::connectToHostEncrypted: TLS initialization failed

which is the result of the OpenSSL libary not being included in the binary as a dependency. So basically, adding a static OpenSSL library to the project file does not work or I am doing something incorrectly somewhere down the line.

Note 4: Why isn't the question titled: How to Import a static library into Qt?

Importing a static library is straight forward and not complicated. I am assuming I have made a mistake somewhere in the static compilation of Qt with SSL support enabled.

Advice on solving this problem would be greatly appreciated.


Update 1

I have resolved the problem with -openssl-linked. The cause (or fix rather) is to not install OpenSSL to your machine. Rather, extract the .a & include directries into a seperate directory. So everything is the same with exception of you having the libs & include without installing.

Then use the standard configureation (mentioned above), replacing -openssl with -openssl-linked and you should have a successful compile.

Updated Problem

When building & running my application with the new Linked OpenSSL Qt kit, I get a message saying:

The code execution cannot proceed because libcrypto.dll was not found. Reinstalling the program may fix this problem.

Followed by another dialog

The code execution cannot proceed because libssl.dll was not found. Reinstalling the program may fix this problem

LDD requirments:

Start-Process -PassThru .\MyAwesomeApp.exe | Get-Process -Module

   Size(K) ModuleName                                         FileName
   ------- ----------                                         --------
     22708 MyAwesomeApp.exe                                     C:\Users\CybeX\QtProjects\build-MyAwesomeApp-Desktop_Qt_OpenSSL_Linked_5_13_1_MinGW_32bit-Release\release\MyAwesomeApp.exe
      1924 ntdll.dll                                          C:\WINDOWS\SYSTEM32\ntdll.dll
       328 wow64.dll                                          C:\WINDOWS\System32\wow64.dll
       480 wow64win.dll                                       C:\WINDOWS\System32\wow64win.dll
        40 wow64cpu.dll                                       C:\WINDOWS\System32\wow64cpu.dll

Have tested this with and without the .pro LIBS & INCLUDEPATH. Both result in the missing dll's required.

like image 730
CybeX Avatar asked Jul 07 '26 06:07

CybeX


1 Answers

The -openssl configuration option configures Qt to load libopenssl dynamically using LoadLibrary or another platform equivalent function. Therefore from this point on all your efforts are futile. You need to go back and solve the -openssl-linked problem.

like image 158
n. 1.8e9-where's-my-share m. Avatar answered Jul 11 '26 07:07

n. 1.8e9-where's-my-share m.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!