Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-115719

When I build with OPENSSL_NO_DEPRECATED_3_0, toPem method in qtlskey_openssl also returns empty string

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Out of scope
    • Not Evaluated
    • None
    • None
    • Network: SSL
    • None

    Description

      When I build with OPENSSL_NO_DEPRECATED_3_0, 

      when I call <Key>.toPem(), it returns empty string.

      QByteArray TlsKeyOpenSSL::toPem(const QByteArray &passPhrase) const
      {
          if (!QSslSocket::supportsSsl() || isNull() || algorithm() == QSsl::Opaque)
              return {};    const EVP_CIPHER *cipher = nullptr;
          if (type() == QSsl::PrivateKey && !passPhrase.isEmpty()) {
      #ifndef OPENSSL_NO_DES
              cipher = q_EVP_des_ede3_cbc();
      #else
              return {};
      #endif
          }    BIO *bio = q_BIO_new(q_BIO_s_mem());
          if (!bio)
              return {};    const auto bioRaii = qScopeGuard([bio]{q_BIO_free(bio);});#ifndef OPENSSL_NO_DEPRECATED_3_0#define write_pubkey(alg, key) q_PEM_write_bio_##alg##_PUBKEY(bio, key)
      #define write_privatekey(alg, key) \
              q_PEM_write_bio_##alg##PrivateKey(bio, key, cipher, (uchar *)passPhrase.data(), \
              passPhrase.size(), nullptr, nullptr)#else#define write_pubkey(alg, key) q_PEM_write_bio_PUBKEY(bio, genericKey)
      #define write_privatekey(alg, key) \
          q_PEM_write_bio_PrivateKey_traditional(bio, genericKey, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)#endif // OPENSSL_NO_DEPRECATED_3_0    bool fail = false;
          if (algorithm() == QSsl::Rsa) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(RSA, rsa))
                      fail = true;
              } else if (!write_privatekey(RSA, rsa)) {
                  fail = true;
              }
          } else if (algorithm() == QSsl::Dsa) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(DSA, dsa))
                      fail = true;
              } else if (!write_privatekey(DSA, dsa)) {
                  fail = true;
              }
          } else if (algorithm() == QSsl::Dh) {
      #ifdef OPENSSL_NO_DEPRECATED_3_0
              EVP_PKEY *result = genericKey;
      #else
              EVP_PKEY *result = q_EVP_PKEY_new();
              const auto guard = qScopeGuard([result]{if (result) q_EVP_PKEY_free(result);});
              if (!result || !q_EVP_PKEY_set1_DH(result, dh)) {
                  fail = true;
              } else
      #endif
              if (type() == QSsl::PublicKey) {
                  if (!q_PEM_write_bio_PUBKEY(bio, result))
                      fail = true;
              } else if (!q_PEM_write_bio_PrivateKey(bio, result, cipher, (uchar *)passPhrase.data(),
                                                     passPhrase.size(), nullptr, nullptr)) {
                  fail = true;
              }
      #ifndef OPENSSL_NO_EC
          } else if (algorithm() == QSsl::Ec) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(EC, ec))
                      fail = true;
              } else {
                  if (!write_privatekey(EC, ec))
                      fail = true;
              }
      #endif
          } else {
              fail = true;
          }    QByteArray pem;
          if (!fail) {
              char *data = nullptr;
              const long size = q_BIO_get_mem_data(bio, &data);
              if (size > 0 && data)
                  pem = QByteArray(data, size);
          } else {
              QTlsBackendOpenSSL::logAndClearErrorQueue();
          }    return pem;
      }void TlsKeyOpenSSL::fromHandle(Qt::HANDLE handle, QSsl::KeyType expectedType)
      {
          EVP_PKEY *evpKey = reinterpret_cast<EVP_PKEY *>(handle);
          if (!evpKey || !fromEVP_PKEY(evpKey)) {
              opaque = evpKey;
              keyAlgorithm = QSsl::Opaque;
          } else {
              q_EVP_PKEY_free(evpKey);
          }    keyType = expectedType;
          keyIsNull = !opaque;
      }

       

      Will it be possible to adapt the implementation, as genericKey is  the variable that contains the key  (rsa, dsa, ec, these variables are empty):

      QByteArray TlsKeyOpenSSL::toPem(const QByteArray &passPhrase) const
      {
          if (!QSslSocket::supportsSsl() || isNull() || algorithm() == QSsl::Opaque)
              return {};    const EVP_CIPHER *cipher = nullptr;
          if (type() == QSsl::PrivateKey && !passPhrase.isEmpty()) {
      #ifndef OPENSSL_NO_DES
              cipher = q_EVP_des_ede3_cbc();
      #else
              return {};
      #endif
          }    BIO *bio = q_BIO_new(q_BIO_s_mem());
          if (!bio)
              return {};    const auto bioRaii = qScopeGuard([bio]{q_BIO_free(bio);});#define write_pubkey(alg, key) q_PEM_write_bio_##alg##_PUBKEY(bio, key)
      #define write_privatekey(alg, key) \
              q_PEM_write_bio_##alg##PrivateKey(bio, key, cipher, (uchar *)passPhrase.data(), \
              passPhrase.size(), nullptr, nullptr)    bool fail = false;
      #ifndef OPENSSL_NO_DEPRECATED_3_0    
              EVP_PKEY *result = genericKey;
              if (type() == QSsl::PublicKey) {
                  if (!q_PEM_write_bio_PUBKEY(bio, result))
                      fail = true;
              } else if (!q_PEM_write_bio_PrivateKey(bio, result, cipher, (uchar *)passPhrase.data(),
                                                     passPhrase.size(), nullptr, nullptr)) {
                  fail = true;
              }
      #else
          if (algorithm() == QSsl::Rsa) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(RSA, rsa))
                      fail = true;
              } else if (!write_privatekey(RSA, rsa)) {
                  fail = true;
              }
          } else if (algorithm() == QSsl::Dsa) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(DSA, dsa))
                      fail = true;
              } else if (!write_privatekey(DSA, dsa)) {
                  fail = true;
              }
          } else if (algorithm() == QSsl::Dh) {
              EVP_PKEY *result = q_EVP_PKEY_new();
              const auto guard = qScopeGuard([result]{if (result) q_EVP_PKEY_free(result);});
              if (!result || !q_EVP_PKEY_set1_DH(result, dh)) {
                  fail = true;
              } else if (type() == QSsl::PublicKey) {
                  if (!q_PEM_write_bio_PUBKEY(bio, result))
                      fail = true;
              } else if (!q_PEM_write_bio_PrivateKey(bio, result, cipher, (uchar *)passPhrase.data(),
                                                     passPhrase.size(), nullptr, nullptr)) {
                  fail = true;
              }
      #ifndef OPENSSL_NO_EC
          } else if (algorithm() == QSsl::Ec) {
              if (type() == QSsl::PublicKey) {
                  if (!write_pubkey(EC, ec))
                      fail = true;
              } else {
                  if (!write_privatekey(EC, ec))
                      fail = true;
              }
      #endif
          } else {
              fail = true;
          }
      #endif    QByteArray pem;
          if (!fail) {
              char *data = nullptr;
              const long size = q_BIO_get_mem_data(bio, &data);
              if (size > 0 && data)
                  pem = QByteArray(data, size);
          } else {
              QTlsBackendOpenSSL::logAndClearErrorQueue();
          }
          return pem;
      }
      

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            tpochep Timur Pocheptsov
            mccarey soguy gueye
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes