Статически скомпилированный Qt 5.13.1 с OpenSSL 1.1.1d, создающий QSslSocket :: connectToHostEncrypted: инициализация TLS не удалась - PullRequest
1 голос
/ 01 октября 2019

Чего я пытаюсь достичь?

Мне нужно создать портативное (все-в-одном) приложение с поддержкой SSL.

В чем проблема?

Итак, основная проблема, с которой я сталкиваюсь, заключается в том, чтобы включить поддержку SSL в мое двоичное / портативное приложение.

A MCVE приложения просто:

Проект .pro Файл

QT -= gui
QT += network

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

SOURCES += \
        main.cpp

INSTALLS += target

Проект 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();
}

  • Вывод на мою DEV машину :

    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"

Информация о 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

  • Запуск того же самого двоичного файла на новой машине с Windows 10 x86 приводит к:

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

Информация о тестовой машине (Совершенно новая установка - 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.

  • Запуск того же двоичного файла на новой машине с Windows 7 x64 приводит к:

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

Информация о тестовой машине (ноутбук с Windows 7 x64 с установленными драйверами)

    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.

На основании приведенных выше результатов я пришел к выводучто установка OpenSSL решает проблему. Хорошо, но я хочу, чтобы он был включен в мое портативное приложение.

Для достижения этой цели мне необходимо

  1. Статическая компиляция Qt с поддержкой OpenSSL

Я сделал это с помощью этого сценария , адаптированного из ps1 сценария powershell найденного здесь, на вики Qt . Я сделал дополнения для:

  • OpenSSL home $OPENSSL_HOME

  • количество потоков $threads и

  • тип архитектуры $arch, который будет использоваться.

Конфигурация следующая:

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)"

Примечание 1:

Я использую -openssl, а не -openssl-linked. Я пробовал несколько вариантов сборки Qt с -openssl и -openssl-linked. -openssl-linked никогда не смог бы успешно построить, см. этот пост Я объяснил причину.

Примечание 2:

Единственная успешная статическая компиляция Qt, с которой я работал, была с -ssl -openssl включенными флагами конфигурации

Установка OpenSSL в

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

, где я использую библиотеки MinGW, обнаружилв

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

с файлами

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

Добавление проекта ссылки .pro в библиотеки OpenSSL

Я добавил библиотеки OpenSSL в файл .pro (с использованием предварительно скомпилированного Qt, построенного на OpenSSL 1.1.1d - показано на рисунке)выше)

QT -= gui
QT += network

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

Примечание 3

Размер двоичного файла с вышеуказанными связанными библиотеками и без них остается одинаковым

Вывод LDD двоичного файла (на моем компьютере разработчика) с добавленными выше библиотеками:

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

Вывод LDD двоичного файла (на моем компьютере с тестовой системой Windows 10 x86) с добавленными выше библиотеками:

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

Оба SSL info выходы одинаковы

Вывод при запросе SSL-соединения на машинах не-Dev:

QSslSocket:: connectToHostEncrypted: инициализация TLS завершилась неудачно

, что является результатом того, что библиотека OpenSSL не включена.

Таким образом, добавление статической библиотеки OpenSSL в файл проекта не работает илия делаю это неправильно?

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Я думаю, что вам нужно установить openSSL на тестовом компьютере, можете сделать это здесь https://code.google.com/archive/p/openssl-for-windows/downloads

Найдено в этой теме

0 голосов
/ 16 октября 2019

OpenSSL Thread Local Storage определяется "загруженной библиотекой" для каждого исходного кода Qt. Затем вам нужно убедиться, что либо библиотека, статически связанная с вашим исполняемым файлом, ИЛИ доступная по пути.

if (!supportsSsl()) {
    qCWarning(lcSsl, "QSslSocket::connectToHostEncrypted: TLS initialization failed");
    d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
    return;
}

, а как насчет supportsSsl()?

/*!
    \internal

    Does the minimum amount of initialization to determine whether SSL
    is supported or not.
*/

bool QSslSocketPrivate::supportsSsl()
{
    return ensureLibraryLoaded();
}

Но что «загруженная библиотека» является немного более «глубокой» концепцией для исходного кода Qt здесь:

bool QSslSocketPrivate::ensureLibraryLoaded()
{
    if (!q_resolveOpenSslSymbols())
        return false;

    const QMutexLocker locker(qt_opensslInitMutex);

    if (!s_libraryLoaded) {
        // Initialize OpenSSL.
        if (q_OPENSSL_init_ssl(0, nullptr) != 1)
            return false;
        q_SSL_load_error_strings();
        q_OpenSSL_add_all_algorithms();

        QSslSocketBackendPrivate::s_indexForSSLExtraData
            = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
                                        nullptr, nullptr);

        // Initialize OpenSSL's random seed.
        if (!q_RAND_status()) {
            qWarning("Random number generator not seeded, disabling SSL support");
            return false;
        }

        s_libraryLoaded = true;
    }
    return true;
}

Пока это не сеанс удаленной отладки, и ответ на этот вопрос имеет значение, вам нужнособерите библиотеку Qt в режиме DEBUG с символами (или будьте готовы использовать их для сборки DEBUG), а затем просто установите точку останова в этой функции и найдите последнюю деталь, препятствующую вашему приложению Qt использовать OpenSSL.

Ответот отладчика следует указать причину этого «инициализация TLS не удалась».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...