Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Which version of QT supports TLS1.2

Which version of QT supports TLS1.2

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 2.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    duan
    wrote on last edited by
    #1
    1. The problem :
      (1) the HTTPS communication mode is upgraded from TLSv1.0 to TLSv1.2, QT communication fails, what is the cause;
      (2) Which version of QT supports TLS1.2?

    2. Development environment: Fedora 14, QT5.3.2, openssl1.0.2;

    3. Fedora14 comes with openssl1.0.0, because openssl1.0.0 does not support TLS1.2, so openssl is upgraded to 1.0.2

    4. The code QSslSocket->setProtocol(QSsl::TLSv1_0), at this time TLSv1.0 connects to the server successfully, but setProtocol(QSsl::TLSv1_2) error log "Unable to init SSL Context: ".

    5. logs as follow:
      20-10-16 15:22:48 Pivotal(csocket.cpp | 407): connect to "187.72.72.78"
      20-10-16 15:22:48 Debug(sslhelper.cpp | 124): socket Mode Change: 1
      20-10-16 15:22:48 Error(csocket.cpp | 1530): sslsocket error: QAbstractSocket::SocketError( 21 ) "Error creating SSL context ()"
      20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1021 "Error creating SSL context ()"
      20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1021 "Error creating SSL context ()"
      20-10-16 15:22:48 Error(csocket.cpp | 1530): sslsocket error: QAbstractSocket::SocketError( 20 ) "Unable to init SSL Context: "
      20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1020 "Unable to init SSL Context: "
      20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1020 "Unable to init SSL Context: "
      20-10-16 15:22:48 Error(csocket.cpp | 1530): sslsocket error: QAbstractSocket::SocketError( 20 ) "Unable to init SSL Context: "
      20-10-16 15:22:48 Error(chttpclient.cpp | 1049): http client error: 1020 "Unable to init SSL Context: "
      20-10-16 15:22:48 Trace(cnetworkheader.cpp | 31): A CNetworkHeader delete: 0xbfcbb174
      20-10-16 15:22:48 Debug(tscsnetworkaccess.cpp | 303): first request post code 1020 content "" header ""
      20-10-16 15:22:48 Error(cnetworkreply.cpp | 148): error: 1020 "Unable to init SSL Context: "
      20-10-16 15:22:48 Error(tscsnetworkaccess.cpp | 365): network error: 1020 "Unable to init SSL Context: "

    1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #9

      If it would not be implemented than the enum would not be there or there would be a comment about this. But you've the Qt source code, take a look by yourself.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      D 1 Reply Last reply
      0
      • D Offline
        D Offline
        duan
        wrote on last edited by
        #2
        This post is deleted!
        1 Reply Last reply
        0
        • D Offline
          D Offline
          duan
          wrote on last edited by
          #3

          code print log,as follows:
          qDebug() << QSslSocket::supportsSsl() << QSslSocket::sslLibraryVersionNumber() << QSslSocket::sslLibraryVersionString();

          output :
          20-10-21 18:48:39 Debug(main.cpp | 96): true 268443839 "OpenSSL 1.0.2k 26 Jan 2017"

          Help document of QT5.3.2 is as follows(https://doc.qt.io/archives/qt-5.5/qssl.html#SslProtocol-enum):I want to know what the value of th question mark means, , whether TLSV1.2 is realized ?

          Constant Value Description
          QSsl::SslV3 0 SSLv3
          QSsl::SslV2 1 SSLv2
          QSsl::TlsV1_0 2 TLSv1.0
          QSsl::TlsV1 TlsV1_0 Obsolete, means the same as TlsV1_0
          QSsl::TlsV1_1 ? TLSv1.1
          QSsl::TlsV1_2 ? TLSv1.2
          QSsl::UnknownProtocol -1 The cipher's protocol cannot be determined.
          QSsl::AnyProtocol ? The socket understands SSLv2, SSLv3, and TLSv1.0. This value is used by QSslSocket only.
          QSsl::TlsV1SslV3 ? this will send a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections.
          QSsl::SecureProtocols ? The default option, using protocols known to be secure; currently behaves like TlsV1SslV3.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #4

            Hi and welcome to devnet,

            First thing to start: using an OpenSSL version that is 3 years old for secure connection is a bad idea.

            Second, Qt 5.3.2 is more than outdated. Current version is 5.15.1 with 6.0 entering beta.

            You should really consider updating your development system.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            D 1 Reply Last reply
            1
            • SGaistS SGaist

              Hi and welcome to devnet,

              First thing to start: using an OpenSSL version that is 3 years old for secure connection is a bad idea.

              Second, Qt 5.3.2 is more than outdated. Current version is 5.15.1 with 6.0 entering beta.

              You should really consider updating your development system.

              D Offline
              D Offline
              duan
              wrote on last edited by
              #5

              @SGaist said in Which version of QT supports TLS1.2:

              Hi and welcome to devnet,

              First thing to start: using an OpenSSL version that is 3 years old for secure connection is a bad idea.

              Second, Qt 5.3.2 is more than outdated. Current version is 5.15.1 with 6.0 entering beta.

              You should really consider updating your development system.

              Thank you,

              1. Regarding the operating system, since hundreds of thousands of devices in production are all Fedora 14, updating the operating system to the latest version Fedora 31 is not realistic.
              2. Regarding the QT version, I want to use the new version QT5.11, but QT5.11 cannot be installed on Fedora 14.
              3. Regarding secure connection, It is no problem to update the Openssl version from 1.0.2 to 1.1.1. The purpose is to use TLS1.2.

              My questions:

              1. I learned that Openssl has supported TLS1.2 since 1.0.1, but I does not know which version of QT supports TLS1.2.
              2. It is understood that Openssl has supported TLS1.2 since 1.0.1, but I does not know which version of QT supports TLS1.2. In the help documentation of QT5.3.2, there is a constant QSsl::TlsV1_2, but its value is Question mark. I don’t know whether QT5.3.2 supports TlsV1.2. But after QT5.11, the value of QSsl::TlsV1_2 changed from question mark to 4
              1 Reply Last reply
              0
              • Christian EhrlicherC Online
                Christian EhrlicherC Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @duan said in Which version of QT supports TLS1.2:

                but its value is Question mark

                Don't know why it's so important to know the value (and why not simply looking at your sources - it's a plain enum) but https://doc.qt.io/qt-5/qssl.html - it's 4

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                D 2 Replies Last reply
                1
                • Christian EhrlicherC Christian Ehrlicher

                  @duan said in Which version of QT supports TLS1.2:

                  but its value is Question mark

                  Don't know why it's so important to know the value (and why not simply looking at your sources - it's a plain enum) but https://doc.qt.io/qt-5/qssl.html - it's 4

                  D Offline
                  D Offline
                  duan
                  wrote on last edited by
                  #7
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @duan said in Which version of QT supports TLS1.2:

                    but its value is Question mark

                    Don't know why it's so important to know the value (and why not simply looking at your sources - it's a plain enum) but https://doc.qt.io/qt-5/qssl.html - it's 4

                    D Offline
                    D Offline
                    duan
                    wrote on last edited by
                    #8

                    @Christian-Ehrlicher
                    Thank you ,

                    1. In the help documentation of QT5.3.2, as follows,

                    Constant Value Description
                    QSsl::SslV3 0 SSLv3
                    QSsl::SslV2 1 SSLv2
                    QSsl::TlsV1_0 2 TLSv1.0
                    QSsl::TlsV1_1 ? TLSv1.1
                    QSsl::TlsV1_2 ? TLSv1.2
                    QSsl::UnknownProtocol -1 The cipher's protocol cannot be determined.
                    QSsl::AnyProtocol ? The socket understands SSLv2, SSLv3, and TLSv1.0. This value is used by QSslSocket only.

                    1. the source code of Q5.3.2 , as follows,
                      enum SslProtocol {
                      SslV3,
                      SslV2,
                      TlsV1_0,
                      #if QT_DEPRECATED_SINCE(5,0)
                      TlsV1 = TlsV1_0,
                      #endif
                      TlsV1_1,
                      TlsV1_2,
                      AnyProtocol,
                      UnknownProtocol = -1
                      };

                    2. See above,the source code of Q5.3.2 has constant QSsl::TlsV1_2.
                      My code setProtocol(QSsl::TLSv1_2) error "Unable to init SSL Context".
                      My code setProtocol(QSsl::TLSv1_0), this connects to the server successfully.

                    So I wonder whether Q5.3.2 implements TLS1.2?

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      If it would not be implemented than the enum would not be there or there would be a comment about this. But you've the Qt source code, take a look by yourself.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      D 1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        If it would not be implemented than the enum would not be there or there would be a comment about this. But you've the Qt source code, take a look by yourself.

                        D Offline
                        D Offline
                        duan
                        wrote on last edited by duan
                        #10

                        @Christian-Ehrlicher
                        Thank you ,
                        Now, I don’t know what causes sslContext->ctx to be NULL, or how to debug this problem?

                        1. code of printing OpenSSL version is as follows:
                          qDebug() << QSslSocket::supportsSsl() << QSslSocket::sslLibraryVersionNumber() << QSslSocket::sslLibraryVersionString();

                        log of outputing OpenSSL version :
                        20-10-21 18:48:39 Debug(main.cpp | 96): true 268443839 "OpenSSL 1.0.2k 26 Jan 2017"

                        1. My code error log is as follows :
                          20-10-16 15:22:48 Pivotal(csocket.cpp | 407): connect to "187.72.72.78"
                          20-10-16 15:22:48 Debug(sslhelper.cpp | 124): socket Mode Change: 1
                          20-10-16 15:22:48 Error(csocket.cpp | 1530): sslsocket error: QAbstractSocket::SocketError( 21 ) "Error creating SSL context ()"
                          20-10-16 15:22:48 Error(chttpclient.cpp | 1271): http client error: 1021 "Error creating SSL context ()"

                        2. I checked the source code of Q5.3.2 and found that there is a constant “case QSsl::TlsV1_2” judgment. The error message "Error creating SSL context (%1)" appears in the code below, and sslContext->ctx is NULL.

                        QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
                        
                        {
                            QSslContext *sslContext = new QSslContext();
                            sslContext->sslConfiguration = configuration;
                            sslContext->errorCode = QSslError::NoError;
                        
                            bool client = (mode == QSslSocket::SslClientMode);
                        
                            bool reinitialized = false;
                        init_context:
                            switch (sslContext->sslConfiguration.protocol()) {
                            case QSsl::SslV2:
                        #ifndef OPENSSL_NO_SSL2
                                sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
                        #else
                                sslContext->ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error
                        #endif
                                break;
                            case QSsl::SslV3:
                                sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
                                break;
                            case QSsl::SecureProtocols: // SslV2 will be disabled below
                            case QSsl::TlsV1SslV3: // SslV2 will be disabled below
                            case QSsl::AnyProtocol:
                            default:
                                sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
                                break;
                            case QSsl::TlsV1_0:
                                sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
                                break;
                            case QSsl::TlsV1_1:
                        #if OPENSSL_VERSION_NUMBER >= 0x10001000L
                                sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
                        #else
                                sslContext->ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error
                        #endif
                                break;
                            case QSsl::TlsV1_2:
                        #if OPENSSL_VERSION_NUMBER >= 0x10001000L
                                sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
                        #else
                                sslContext->ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error
                        #endif
                                break;
                            }
                            if (!sslContext->ctx) {
                                // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
                                // by re-initializing the library.
                                if (!reinitialized) {
                                    reinitialized = true;
                                    if (q_SSL_library_init() == 1)
                                        goto init_context;
                                }
                        
                                sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                sslContext->errorCode = QSslError::UnspecifiedError;
                                return sslContext;
                            }
                        
                            // Enable bug workarounds.
                            long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
                            q_SSL_CTX_set_options(sslContext->ctx, options);
                        
                        #if OPENSSL_VERSION_NUMBER >= 0x10000000L
                            // Tell OpenSSL to release memory early
                            // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
                            if (q_SSLeay() >= 0x10000000L)
                                q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
                        #endif
                        
                            // Initialize ciphers
                            QByteArray cipherString;
                            int first = true;
                            QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
                            if (ciphers.isEmpty())
                                ciphers = QSslSocketPrivate::defaultCiphers();
                            foreach (const QSslCipher &cipher, ciphers) {
                                if (first)
                                    first = false;
                                else
                                    cipherString.append(':');
                                cipherString.append(cipher.name().toLatin1());
                            }
                        
                            if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
                                sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                sslContext->errorCode = QSslError::UnspecifiedError;
                                return sslContext;
                            }
                        
                            // Add all our CAs to this store.
                            foreach (const QSslCertificate &caCertificate, sslContext->sslConfiguration.caCertificates()) {
                                // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
                                //
                                // If several CA certificates matching the name, key identifier, and
                                // serial number condition are available, only the first one will be
                                // examined. This may lead to unexpected results if the same CA
                                // certificate is available with different expiration dates. If a
                                // ``certificate expired'' verification error occurs, no other
                                // certificate will be searched. Make sure to not have expired
                                // certificates mixed with valid ones.
                                //
                                // See also: QSslSocketBackendPrivate::verify()
                                if (caCertificate.expiryDate() >= QDateTime::currentDateTime()) {
                                    q_X509_STORE_add_cert(sslContext->ctx->cert_store, (X509 *)caCertificate.handle());
                                }
                            }
                        
                            if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
                                // tell OpenSSL the directories where to look up the root certs on demand
                                QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
                                for (int a = 0; a < unixDirs.count(); ++a)
                                    q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDirs.at(a).constData());
                            }
                        
                            if (!sslContext->sslConfiguration.localCertificate().isNull()) {
                                // Require a private key as well.
                                if (sslContext->sslConfiguration.privateKey().isNull()) {
                                    sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                    sslContext->errorCode = QSslError::UnspecifiedError;
                                    return sslContext;
                                }
                        
                                // Load certificate
                                if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
                                    sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                    sslContext->errorCode = QSslError::UnspecifiedError;
                                    return sslContext;
                                }
                        
                                if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
                                    sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
                                } else {
                                    // Load private key
                                    sslContext->pkey = q_EVP_PKEY_new();
                                    // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
                                    // this lead to a memory leak. Now we use the *_set1_* functions which do not
                                    // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
                                    if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
                                        q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
                                    else
                                        q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
                                }
                        
                                if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
                                    sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                    sslContext->errorCode = QSslError::UnspecifiedError;
                                    return sslContext;
                                }
                                if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
                                    sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey
                        
                                // Check if the certificate matches the private key.
                                if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
                                    sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
                                    sslContext->errorCode = QSslError::UnspecifiedError;
                                    return sslContext;
                                }
                        
                                // If we have any intermediate certificates then we need to add them to our chain
                                bool first = true;
                                foreach (const QSslCertificate &cert, configuration.d->localCertificateChain) {
                                    if (first) {
                                        first = false;
                                        continue;
                                    }
                                    q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
                                                   q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
                                }
                            }
                        
                            // Initialize peer verification.
                            if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
                                q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
                            } else {
                                q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
                            }
                        
                            // Set verification depth.
                            if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
                                q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
                        
                            // set persisted session if the user set it
                            if (!configuration.sessionTicket().isEmpty())
                                sslContext->setSessionASN1(configuration.sessionTicket());
                        
                            // Set temp DH params
                            DH *dh = 0;
                            dh = get_dh1024();
                            q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
                            q_DH_free(dh);
                        
                        #ifndef OPENSSL_NO_EC
                            // Set temp ECDH params
                            EC_KEY *ecdh = 0;
                            ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
                            q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh);
                            q_EC_KEY_free(ecdh);
                        #endif // OPENSSL_NO_EC
                        
                            return sslContext;
                        }
                        
                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved