LCOV - code coverage report
Current view: top level - crypto-lib - libcryptofunction.cpp (source / functions) Coverage Total Hit
Test: QtApplicationManager Lines: 65.4 % 52 34
Test Date: 2024-11-23 10:23:45 Functions: 100.0 % 3 3
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 33.9 % 56 19

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2021 The Qt Company Ltd.
       2                 :             : // Copyright (C) 2019 Luxoft Sweden AB
       3                 :             : // Copyright (C) 2018 Pelagicore AG
       4                 :             : // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
       5                 :             : 
       6                 :             : #include <QLibrary>
       7                 :             : #include <QString>
       8                 :             : #include <QSslSocket>
       9                 :             : 
      10                 :             : #include "libcryptofunction.h"
      11                 :             : 
      12                 :             : // we want at least openssl 1.0.1 or 1.1.0
      13                 :             : #define QT_AM_MINIMUM_OPENSSL10_VERSION 0x1000100fL
      14                 :             : #define QT_AM_MINIMUM_OPENSSL11_VERSION 0x1010000fL
      15                 :             : #define QT_AM_MINIMUM_OPENSSL30_VERSION 0x3000000fL
      16                 :             : 
      17                 :             : QT_BEGIN_NAMESPACE_AM
      18                 :             : 
      19                 :             : // clazy:excludeall=non-pod-global-static
      20                 :             : // AXIVION DISABLE Qt-NonPodGlobalStatic
      21                 :             : 
      22                 :             : static QT_AM_LIBCRYPTO_FUNCTION(SSLeay, unsigned long(*)(), 0);
      23                 :             : static QT_AM_LIBCRYPTO_FUNCTION(OPENSSL_add_all_algorithms_noconf, void(*)());
      24                 :             : static QT_AM_LIBCRYPTO_FUNCTION(ERR_load_crypto_strings, void(*)());
      25                 :             : 
      26                 :             : static QT_AM_LIBCRYPTO_FUNCTION(OpenSSL_version_num, unsigned long(*)(), 0);
      27                 :             : static QT_AM_LIBCRYPTO_FUNCTION(OPENSSL_init_crypto, int(*)(uint64_t, void *), 0);
      28                 :             : 
      29                 :             : struct OSSL_PROVIDER;
      30                 :             : struct OSSL_LIB_CTX;
      31                 :             : static QT_AM_LIBCRYPTO_FUNCTION(OSSL_PROVIDER_load, OSSL_PROVIDER *(*)(OSSL_LIB_CTX *, const char *), nullptr);
      32                 :             : 
      33                 :             : // AXIVION ENABLE Qt-NonPodGlobalStatic
      34                 :             : 
      35                 :             : QLibrary *Cryptography::LibCryptoFunctionBase::s_library = nullptr;
      36                 :             : bool Cryptography::LibCryptoFunctionBase::s_isOpenSSL11 = false;
      37                 :             : bool Cryptography::LibCryptoFunctionBase::s_isOpenSSL30 = false;
      38                 :             : 
      39                 :           3 : bool Cryptography::LibCryptoFunctionBase::initialize(bool loadOpenSsl3LegacyProvider)
      40                 :             : {
      41         [ +  - ]:           3 :     if (s_library)
      42                 :             :         return true;
      43                 :             : 
      44                 :           3 :     const char *libname =
      45                 :             : #ifdef Q_OS_WIN32
      46                 :             :             "libeay32";
      47                 :             : #else
      48                 :             :             "crypto";
      49                 :             : #endif
      50                 :             : 
      51                 :             :     // Loading libcrypto is a mess, since distros are not creating links for libcrypto.so.1
      52                 :             :     // anymore. In order to not duplicate a lot of bad hacks, we simply let QtNetwork do the
      53                 :             :     // dirty work.
      54         [ +  - ]:           3 :     if (!QSslSocket::supportsSsl())
      55                 :             :         return false;
      56                 :             : 
      57   [ +  -  +  - ]:           3 :     s_library = new QLibrary(QString::fromLatin1(libname), 1);
      58                 :           3 :     bool ok = s_library->load();
      59         [ +  - ]:           3 :     if (!ok) {
      60   [ +  -  +  - ]:           9 :         s_library->setFileNameAndVersion(QString::fromLatin1(libname), QString());
      61                 :           3 :         ok = s_library->load();
      62                 :             :     }
      63         [ +  - ]:           3 :     if (ok) {
      64                 :           3 :         unsigned long version = 0;
      65                 :             : 
      66   [ +  -  +  - ]:           6 :         if (am_OpenSSL_version_num.functionPointer())
      67                 :           3 :             version = am_OpenSSL_version_num();  // 1.1 and 3.x
      68   [ #  #  #  # ]:           0 :         else if (am_SSLeay.functionPointer())
      69                 :           0 :             version = am_SSLeay(); // 1.0
      70                 :             : 
      71         [ +  - ]:           3 :         if (version > 0) {
      72         [ +  - ]:           3 :             if (version >= QT_AM_MINIMUM_OPENSSL11_VERSION) {
      73                 :           3 :                 s_isOpenSSL11 = true;
      74                 :             : 
      75         [ +  - ]:           3 :                 if (version >= QT_AM_MINIMUM_OPENSSL30_VERSION) {
      76                 :           3 :                     s_isOpenSSL30 = true;
      77                 :             : 
      78         [ +  + ]:           3 :                     if (loadOpenSsl3LegacyProvider) {
      79                 :             :                         // openSSL 3.0 might need the legacy provider to read old PKCS12 certs
      80                 :           1 :                         auto legacyLoaded = am_OSSL_PROVIDER_load(nullptr, "legacy");
      81                 :           1 :                         auto defaultLoaded = am_OSSL_PROVIDER_load(nullptr, "default");
      82         [ -  + ]:           1 :                         if (!legacyLoaded || !defaultLoaded)
      83                 :           0 :                             qCritical("Loaded libcrypto version 3, but couldn't load the 'legacy provider' as requested");
      84                 :             :                     }
      85                 :             :                 }
      86                 :             : 
      87                 :           3 :                 return (am_OPENSSL_init_crypto(4 /*OPENSSL_INIT_ADD_ALL_CIPHERS*/
      88                 :             :                                                | 8 /*OPENSSL_INIT_ADD_ALL_DIGESTS*/
      89                 :           6 :                                                | 2 /*OPENSSL_INIT_LOAD_CRYPTO_STRINGS*/,
      90                 :           3 :                                                nullptr) == 1);
      91         [ #  # ]:           0 :             } else if (version >= QT_AM_MINIMUM_OPENSSL10_VERSION) {
      92                 :           0 :                 am_OPENSSL_add_all_algorithms_noconf();
      93                 :           0 :                 am_ERR_load_crypto_strings();
      94                 :           0 :                 return true;
      95                 :             :             } else {
      96         [ #  # ]:           0 :                 qCritical("Loaded libcrypto (%s), but the version is too old: 0x%08lx (minimum supported version is: 0x%08lx)",
      97         [ #  # ]:           0 :                           qPrintable(s_library->fileName()), version, QT_AM_MINIMUM_OPENSSL10_VERSION);
      98                 :             :             }
      99                 :             :         } else {
     100                 :           0 :             qCritical("Could not get version information from libcrypto: neither of the symbols 'SSLeay' or 'OpenSSL_version_num' were found");
     101                 :             :         }
     102                 :           0 :         s_library->unload();
     103                 :             :     } else {
     104   [ #  #  #  # ]:           0 :         qCritical("Could not find a suitable libcrypto: %s", qPrintable(s_library->errorString()));
     105                 :             :     }
     106         [ #  # ]:           0 :     delete s_library;
     107                 :           0 :     s_library = nullptr;
     108                 :           0 :     return false;
     109                 :             : }
     110                 :             : 
     111                 :        1301 : Cryptography::LibCryptoFunctionBase::LibCryptoFunctionBase(const char *symbol)
     112                 :        1301 :     : m_symbol(symbol)
     113                 :        1301 : { }
     114                 :             : 
     115                 :          67 : void Cryptography::LibCryptoFunctionBase::resolve()
     116                 :             : {
     117         [ +  - ]:          67 :     if (!m_tried) {
     118         [ -  + ]:          67 :         if (!s_library) {
     119                 :           0 :             qCritical("Failed to resolve libcrypto symbol %s: library not loaded yet", m_symbol);
     120                 :           0 :             return;
     121                 :             :         }
     122                 :          67 :         m_functionPtr = s_library->resolve(m_symbol);
     123         [ -  + ]:          67 :         if (!m_functionPtr)
     124   [ #  #  #  # ]:           0 :             qCritical("Failed to resolve libcrypto symbol %s: %s", m_symbol, qPrintable(s_library->errorString()));
     125                 :          67 :         m_tried = true;
     126                 :             :     }
     127                 :             : }
     128                 :             : 
     129                 :             : QT_END_NAMESPACE_AM
        

Generated by: LCOV version 2.0-1