Ticket #58218: patch-openssl11-support-qt597.diff

File patch-openssl11-support-qt597.diff, 181.6 KB (added by RJVB (René Bertin), 5 years ago)

patch for Qt 5.9; this is a cherry-pick of the official Qt commit that made it into 5.10 but not 5.9 (for whatever political? reason)

  • new file qtbase/config.tests/unix/openssl11/openssl.cpp

    From cfbe03a6e035ab3cce5f04962cddd06bd414dcea Mon Sep 17 00:00:00 2001
    From: "Richard J. Moore" <rich@kde.org>
    Date: Thu, 23 Mar 2017 12:43:22 +0100
    Subject: [PATCH] QSslSocket: OpenSSL 1.1 backend
    MIME-Version: 1.0
    Content-Type: text/plain; charset=utf8
    Content-Transfer-Encoding: 8bit
    
    This patch-set implements a new QSslSocket backend based on OpenSSL 1.1.
    
    General.
    
    The code in this patch was organized to achieve these (somewhat contradicting)
    objectives:
    - keep the new code free of #if-ery, as far as possible;
    - make it easy to clean away dead code when we're eventually able to retire
      out-dated OpenSSL versions;
    - reduce the amount of code duplication.
    
    If changes in some file/component were insignificant (~5 one-liners per file),
    we still use pp-checks like: #if QT_CONFIG(opensslv11) ... #else ... #endif -
    the logic is simple and it's still easy to clean the code if we remove the legacy
    back-end. Where it saved #if-ery, we also introduced 'forward-compatible'
    macros implementing equivalents of 1.1 functions using older OpenSSL.
    
    In case some class contains a lot of version-specific ifdefs (particularly where
    nested #if-ery was complex) we choose to split code into: "pre11" h/cpp files,
    "shared" h/cpp files (they preserve their original names, e.g qsslsocket_openssl.cpp)
    and "11" h/cpp files. If in future we remove the legacy back-end, "pre11" should be
    removed; "shared" and "11" parts - merged.
    
    Configuration.
    
    We introduced a new feature 'opensslv11' which complements the pre-existing
    'openssl' and 'openssl-linked' features. The 'opensslv11' feature is enabled
    by a simple test which either compiles successfully or ends in a compilation
    error, depending on a value of the OPENSSL_VERSION_NUMBER constant. If the
    feature was enabled, we also append an additional compilation flag
    -DOPENSSL_API_COMPAT=0x10100000L to make sure our new code does not contain
    deprecated structures, function calls, macro-invocations from OpenSSL < 1.1.
    
    Change-Id: I2064efbe9685def5d2bb2233a66f7581954fb74a
    Reviewed-by: André Klitzing <aklitzing@gmail.com>
    Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
    
    diff --git a/qtbase/config.tests/unix/openssl11/openssl.cpp b/qtbase/config.tests/unix/openssl11/openssl.cpp
    new file mode 100644
    index 0000000000000000000000000000000000000000..c20cc59debf52697e39927bac6ab56fd5ecddd12
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Contact: https://www.qt.io/licensing/
     5**
     6** This file is part of the config.tests of the Qt Toolkit.
     7**
     8** $QT_BEGIN_LICENSE:LGPL$
     9** Commercial License Usage
     10** Licensees holding valid commercial Qt licenses may use this file in
     11** accordance with the commercial license agreement provided with the
     12** Software or, alternatively, in accordance with the terms contained in
     13** a written agreement between you and The Qt Company. For licensing terms
     14** and conditions see https://www.qt.io/terms-conditions. For further
     15** information use the contact form at https://www.qt.io/contact-us.
     16**
     17** GNU Lesser General Public License Usage
     18** Alternatively, this file may be used under the terms of the GNU Lesser
     19** General Public License version 3 as published by the Free Software
     20** Foundation and appearing in the file LICENSE.LGPL3 included in the
     21** packaging of this file. Please review the following information to
     22** ensure the GNU Lesser General Public License version 3 requirements
     23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     24**
     25** GNU General Public License Usage
     26** Alternatively, this file may be used under the terms of the GNU
     27** General Public License version 2.0 or (at your option) the GNU General
     28** Public license version 3 or any later version approved by the KDE Free
     29** Qt Foundation. The licenses are as published by the Free Software
     30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     31** included in the packaging of this file. Please review the following
     32** information to ensure the GNU General Public License requirements will
     33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     34** https://www.gnu.org/licenses/gpl-3.0.html.
     35**
     36** $QT_END_LICENSE$
     37**
     38****************************************************************************/
     39
     40#include <openssl/opensslv.h>
     41
     42#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L
     43#  error "OpenSSL >= 1.1 is required"
     44#endif
     45
     46int main()
     47{
     48}
  • new file qtbase/config.tests/unix/openssl11/openssl.pro

    diff --git a/qtbase/config.tests/unix/openssl11/openssl.pro b/qtbase/config.tests/unix/openssl11/openssl.pro
    new file mode 100644
    index 0000000000000000000000000000000000000000..a023aee4aa98b5ab0ebb31082ce2893e63900327
    - +  
     1SOURCES = openssl.cpp
     2CONFIG -= x11 qt
  • qtbase/src/network/configure.json

    diff --git a/qtbase/src/network/configure.json b/qtbase/src/network/configure.json
    index 2cf90ed94b7234f00ae5275c15648698226b706f..43debe0895257bb85171f0642021ef4bc7b910cc 100644
    a b  
    146146                ]
    147147            },
    148148            "use": "network"
     149        },
     150        "openssl11": {
     151            "label": "OpenSSL v. 1.1 support",
     152            "type": "compile",
     153            "test": "unix/openssl11",
     154            "use": "network"
    149155        }
    150156    },
    151157
     
    213219            "condition": "config.winrt || features.securetransport || features.openssl",
    214220            "output": [ "publicFeature", "feature" ]
    215221        },
     222        "opensslv11": {
     223            "label": "OpenSSL v. 1.1",
     224            "condition": "tests.openssl11",
     225            "output": ["publicFeature", "feature"]
     226        },
    216227        "sctp": {
    217228            "label": "SCTP",
    218229            "autoDetect": false,
  • qtbase/src/network/ssl/qsslcertificate_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qsslcertificate_openssl.cpp b/qtbase/src/network/ssl/qsslcertificate_openssl.cpp
    index 28b7eda54ae3d7cd4bd6ee7dd0d2b3d8b106065b..71e514a0253060cad443233e293d0bfb400472b3 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
    45** Contact: https://www.qt.io/licensing/
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
    bool QSslCertificate::operator==(const QSslCertificate &other) const 
    6465uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW
    6566{
    6667    if (X509 * const x509 = key.d->x509) {
    67         (void)q_X509_cmp(x509, x509); // populate x509->sha1_hash
    68                                       // (if someone knows a better way...)
    69         return qHashBits(x509->sha1_hash, SHA_DIGEST_LENGTH, seed);
    70     } else {
    71         return seed;
     68        const EVP_MD *sha1 = q_EVP_sha1();
     69        unsigned int len = 0;
     70        unsigned char md[EVP_MAX_MD_SIZE];
     71        q_X509_digest(x509, sha1, md, &len);
     72        return qHashBits(md, len, seed);
    7273    }
     74
     75    return seed;
    7376}
    7477
    7578bool QSslCertificate::isNull() const
    QByteArray QSslCertificate::version() const 
    8992{
    9093    QMutexLocker lock(QMutexPool::globalInstanceGet(d.data()));
    9194    if (d->versionString.isEmpty() && d->x509)
    92         d->versionString =
    93             QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->version)) + 1);
     95        d->versionString = QByteArray::number(qlonglong(q_X509_get_version(d->x509)) + 1);
    9496
    9597    return d->versionString;
    9698}
    QByteArray QSslCertificate::serialNumber() const 
    99101{
    100102    QMutexLocker lock(QMutexPool::globalInstanceGet(d.data()));
    101103    if (d->serialNumberString.isEmpty() && d->x509) {
    102         ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber;
     104        ASN1_INTEGER *serialNumber = q_X509_get_serialNumber(d->x509);
    103105        QByteArray hexString;
    104106        hexString.reserve(serialNumber->length * 3);
    105107        for (int a = 0; a < serialNumber->length; ++a) {
    QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlter 
    199201                continue;
    200202            }
    201203
    202             const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(genName->d.ia5));
     204            const char *altNameStr = reinterpret_cast<const char *>(q_ASN1_STRING_get0_data(genName->d.ia5));
    203205            const QString altName = QString::fromLatin1(altNameStr, len);
    204206            if (genName->type == GEN_DNS)
    205207                result.insert(QSsl::DnsEntry, altName);
    206208            else if (genName->type == GEN_EMAIL)
    207209                result.insert(QSsl::EmailEntry, altName);
    208210        }
    209         q_sk_pop_free((STACK*)altNames, reinterpret_cast<void(*)(void*)>(q_sk_free));
     211
     212        q_OPENSSL_sk_pop_free((OPENSSL_STACK*)altNames, reinterpret_cast<void(*)(void*)>(q_OPENSSL_sk_free));
    210213    }
    211214
    212215    return result;
    QSslKey QSslCertificate::publicKey() const 
    235238    QSslKey key;
    236239
    237240    key.d->type = QSsl::PublicKey;
    238     X509_PUBKEY *xkey = d->x509->cert_info->key;
    239     EVP_PKEY *pkey = q_X509_PUBKEY_get(xkey);
     241
     242    EVP_PKEY *pkey = q_X509_get_pubkey(d->x509);
    240243    Q_ASSERT(pkey);
     244    const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey));
    241245
    242     if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) {
     246    if (keyType == EVP_PKEY_RSA) {
    243247        key.d->rsa = q_EVP_PKEY_get1_RSA(pkey);
    244248        key.d->algorithm = QSsl::Rsa;
    245249        key.d->isNull = false;
    246     } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) {
     250    } else if (keyType == EVP_PKEY_DSA) {
    247251        key.d->dsa = q_EVP_PKEY_get1_DSA(pkey);
    248252        key.d->algorithm = QSsl::Dsa;
    249253        key.d->isNull = false;
    250254#ifndef OPENSSL_NO_EC
    251     } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_EC) {
     255    } else if (keyType == EVP_PKEY_EC) {
    252256        key.d->ec = q_EVP_PKEY_get1_EC_KEY(pkey);
    253257        key.d->algorithm = QSsl::Ec;
    254258        key.d->isNull = false;
    255259#endif
    256     } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DH) {
     260    } else if (keyType == EVP_PKEY_DH) {
    257261        // DH unsupported
    258262    } else {
    259263        // error?
    static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext) 
    275279    X509V3_EXT_METHOD *meth = const_cast<X509V3_EXT_METHOD *>(q_X509V3_EXT_get(ext));
    276280    if (!meth) {
    277281        ASN1_OCTET_STRING *value = q_X509_EXTENSION_get_data(ext);
    278         QByteArray result( reinterpret_cast<const char *>(q_ASN1_STRING_data(value)),
     282        QByteArray result( reinterpret_cast<const char *>(q_ASN1_STRING_get0_data(value)),
    279283                           q_ASN1_STRING_length(value));
    280284        return result;
    281285    }
    static QVariant x509ExtensionToValue(X509_EXTENSION *ext) 
    371375                        continue;
    372376                    }
    373377
    374                     const char *uriStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(name->d.uniformResourceIdentifier));
     378                    const char *uriStr = reinterpret_cast<const char *>(q_ASN1_STRING_get0_data(name->d.uniformResourceIdentifier));
    375379                    const QString uri = QString::fromUtf8(uriStr, len);
    376380
    377381                    result[QString::fromUtf8(QSslCertificatePrivate::asn1ObjectName(ad->method))] = uri;
    static QVariant x509ExtensionToValue(X509_EXTENSION *ext) 
    380384                }
    381385            }
    382386
    383 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    384             q_sk_pop_free((_STACK*)info, reinterpret_cast<void(*)(void*)>(q_sk_free));
    385 #else
    386             q_sk_pop_free((STACK*)info, reinterpret_cast<void(*)(void*)>(q_sk_free));
    387 #endif
     387            q_OPENSSL_sk_pop_free((OPENSSL_STACK*)info, reinterpret_cast<void(*)(void *)>(q_OPENSSL_sk_free));
    388388            return result;
    389389        }
    390390        break;
    static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name) 
    607607        unsigned char *data = 0;
    608608        int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e));
    609609        info.insertMulti(name, QString::fromUtf8((char*)data, size));
     610#if QT_CONFIG(opensslv11)
     611        q_CRYPTO_free(data, 0, 0);
     612#else
    610613        q_CRYPTO_free(data);
     614#endif
    611615    }
    612616
    613617    return info;
    QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) 
    619623    if (!x509 || !QSslSocket::supportsSsl())
    620624        return certificate;
    621625
    622     ASN1_TIME *nbef = q_X509_get_notBefore(x509);
    623     ASN1_TIME *naft = q_X509_get_notAfter(x509);
     626    ASN1_TIME *nbef = q_X509_getm_notBefore(x509);
     627    ASN1_TIME *naft = q_X509_getm_notAfter(x509);
     628
    624629    certificate.d->notValidBefore = q_getTimeFromASN1(nbef);
    625630    certificate.d->notValidAfter = q_getTimeFromASN1(naft);
    626631    certificate.d->null = false;
  • qtbase/src/network/ssl/qsslcontext_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp
    index c92d8fc3f853a84c220f35af3bcc9814c6cb474d..cef503710c8c7860184a82e50c29f9c656cd2291 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
    44** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
    55** Copyright (C) 2014 Governikus GmbH & Co. KG.
    66** Contact: https://www.qt.io/licensing/
     
    4141
    4242
    4343#include <QtNetwork/qsslsocket.h>
    44 #include <QtNetwork/qssldiffiehellmanparameters.h>
    45 #include <QtCore/qmutex.h>
    4644
    4745#include "private/qssl_p.h"
    4846#include "private/qsslcontext_openssl_p.h"
    49 #include "private/qsslsocket_p.h"
    5047#include "private/qsslsocket_openssl_p.h"
    5148#include "private/qsslsocket_openssl_symbols_p.h"
    52 #include "private/qssldiffiehellmanparameters_p.h"
    5349
    5450QT_BEGIN_NAMESPACE
    5551
    56 // defined in qsslsocket_openssl.cpp:
    57 extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
    58 extern QString getErrorsFromOpenSsl();
    59 
    6052QSslContext::QSslContext()
    6153    : ctx(0),
    6254    pkey(0),
    QSslContext::~QSslContext() 
    7870        q_SSL_SESSION_free(session);
    7971}
    8072
    81 static inline QString msgErrorSettingEllipticCurves(const QString &why)
    82 {
    83     return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
    84 }
    85 
    86 // static
    87 void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
    88 {
    89     sslContext->sslConfiguration = configuration;
    90     sslContext->errorCode = QSslError::NoError;
    91 
    92     bool client = (mode == QSslSocket::SslClientMode);
    93 
    94     bool reinitialized = false;
    95     bool unsupportedProtocol = false;
    96 init_context:
    97     switch (sslContext->sslConfiguration.protocol()) {
    98     case QSsl::SslV2:
    99 #ifndef OPENSSL_NO_SSL2
    100         sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
    101 #else
    102         // SSL 2 not supported by the system, but chosen deliberately -> error
    103         sslContext->ctx = 0;
    104         unsupportedProtocol = true;
    105 #endif
    106         break;
    107     case QSsl::SslV3:
    108 #ifndef OPENSSL_NO_SSL3_METHOD
    109         sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
    110 #else
    111         // SSL 3 not supported by the system, but chosen deliberately -> error
    112         sslContext->ctx = 0;
    113         unsupportedProtocol = true;
    114 #endif
    115         break;
    116     case QSsl::SecureProtocols:
    117         // SSLv2 and SSLv3 will be disabled by SSL options
    118         // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32.
    119     case QSsl::TlsV1SslV3:
    120         // SSLv2 will will be disabled by SSL options
    121     case QSsl::AnyProtocol:
    122     default:
    123         sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
    124         break;
    125     case QSsl::TlsV1_0:
    126         sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
    127         break;
    128     case QSsl::TlsV1_1:
    129 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    130         sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
    131 #else
    132         // TLS 1.1 not supported by the system, but chosen deliberately -> error
    133         sslContext->ctx = 0;
    134         unsupportedProtocol = true;
    135 #endif
    136         break;
    137     case QSsl::TlsV1_2:
    138 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    139         sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
    140 #else
    141         // TLS 1.2 not supported by the system, but chosen deliberately -> error
    142         sslContext->ctx = 0;
    143         unsupportedProtocol = true;
    144 #endif
    145         break;
    146     case QSsl::TlsV1_0OrLater:
    147         // Specific protocols will be specified via SSL options.
    148         sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
    149         break;
    150     case QSsl::TlsV1_1OrLater:
    151     case QSsl::TlsV1_2OrLater:
    152 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    153         // Specific protocols will be specified via SSL options.
    154         sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
    155 #else
    156         // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error
    157         sslContext->ctx = 0;
    158         unsupportedProtocol = true;
    159 #endif
    160         break;
    161     }
    162 
    163     if (!sslContext->ctx) {
    164         // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
    165         // by re-initializing the library.
    166         if (!reinitialized) {
    167             reinitialized = true;
    168             if (q_SSL_library_init() == 1)
    169                 goto init_context;
    170         }
    171 
    172         sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
    173             unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
    174         );
    175         sslContext->errorCode = QSslError::UnspecifiedError;
    176         return;
    177     }
    178 
    179     // Enable bug workarounds.
    180     long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
    181     q_SSL_CTX_set_options(sslContext->ctx, options);
    182 
    183 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    184     // Tell OpenSSL to release memory early
    185     // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
    186     if (q_SSLeay() >= 0x10000000L)
    187         q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
    188 #endif
    189 
    190     // Initialize ciphers
    191     QByteArray cipherString;
    192     bool first = true;
    193     QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
    194     if (ciphers.isEmpty())
    195         ciphers = QSslSocketPrivate::defaultCiphers();
    196     for (const QSslCipher &cipher : qAsConst(ciphers)) {
    197         if (first)
    198             first = false;
    199         else
    200             cipherString.append(':');
    201         cipherString.append(cipher.name().toLatin1());
    202     }
    203 
    204     if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
    205         sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    206         sslContext->errorCode = QSslError::UnspecifiedError;
    207         return;
    208     }
    209 
    210     const QDateTime now = QDateTime::currentDateTimeUtc();
    211 
    212     // Add all our CAs to this store.
    213     const auto caCertificates = sslContext->sslConfiguration.caCertificates();
    214     for (const QSslCertificate &caCertificate : caCertificates) {
    215         // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
    216         //
    217         // If several CA certificates matching the name, key identifier, and
    218         // serial number condition are available, only the first one will be
    219         // examined. This may lead to unexpected results if the same CA
    220         // certificate is available with different expiration dates. If a
    221         // ``certificate expired'' verification error occurs, no other
    222         // certificate will be searched. Make sure to not have expired
    223         // certificates mixed with valid ones.
    224         //
    225         // See also: QSslSocketBackendPrivate::verify()
    226         if (caCertificate.expiryDate() >= now) {
    227             q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
    228         }
    229     }
    230 
    231     if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
    232         // tell OpenSSL the directories where to look up the root certs on demand
    233         const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
    234         for (const QByteArray &unixDir : unixDirs)
    235             q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDir.constData());
    236     }
    237 
    238     if (!sslContext->sslConfiguration.localCertificate().isNull()) {
    239         // Require a private key as well.
    240         if (sslContext->sslConfiguration.privateKey().isNull()) {
    241             sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    242             sslContext->errorCode = QSslError::UnspecifiedError;
    243             return;
    244         }
    245 
    246         // Load certificate
    247         if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
    248             sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    249             sslContext->errorCode = QSslError::UnspecifiedError;
    250             return;
    251         }
    252 
    253         if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
    254             sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
    255         } else {
    256             // Load private key
    257             sslContext->pkey = q_EVP_PKEY_new();
    258             // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
    259             // this lead to a memory leak. Now we use the *_set1_* functions which do not
    260             // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
    261             if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
    262                 q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
    263             else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
    264                 q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
    265 #ifndef OPENSSL_NO_EC
    266             else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
    267                 q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
    268 #endif
    269         }
    270 
    271         if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
    272             sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    273             sslContext->errorCode = QSslError::UnspecifiedError;
    274             return;
    275         }
    276         if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
    277             sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey
    278 
    279         // Check if the certificate matches the private key.
    280         if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
    281             sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    282             sslContext->errorCode = QSslError::UnspecifiedError;
    283             return;
    284         }
    285 
    286         // If we have any intermediate certificates then we need to add them to our chain
    287         bool first = true;
    288         for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
    289             if (first) {
    290                 first = false;
    291                 continue;
    292             }
    293             q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
    294                            q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
    295         }
    296     }
    297 
    298     // Initialize peer verification.
    299     if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
    300         q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
    301     } else {
    302         q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
    303     }
    304 
    305     // Set verification depth.
    306     if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
    307         q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
    308 
    309     // set persisted session if the user set it
    310     if (!configuration.sessionTicket().isEmpty())
    311         sslContext->setSessionASN1(configuration.sessionTicket());
    312 
    313     // Set temp DH params
    314     QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters();
    315 
    316     if (!dhparams.isValid()) {
    317         sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid");
    318         sslContext->errorCode = QSslError::UnspecifiedError;
    319         return;
    320     }
    321 
    322     if (!dhparams.isEmpty()) {
    323         const QByteArray &params = dhparams.d->derData;
    324         const char *ptr = params.constData();
    325         DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
    326         if (dh == NULL)
    327             qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form");
    328         q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
    329         q_DH_free(dh);
    330     }
    331 
    332 #ifndef OPENSSL_NO_EC
    333 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
    334     if (q_SSLeay() >= 0x10002000L) {
    335         q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
    336     } else
    337 #endif
    338     {
    339         // Set temp ECDH params
    340         EC_KEY *ecdh = 0;
    341         ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    342         q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh);
    343         q_EC_KEY_free(ecdh);
    344     }
    345 #endif // OPENSSL_NO_EC
    346 
    347 #if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
    348     if (!client)
    349         q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
    350 #endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
    351 
    352     const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
    353     if (!qcurves.isEmpty()) {
    354 #if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
    355         // Set the curves to be used
    356         if (q_SSLeay() >= 0x10002000L) {
    357             // SSL_CTX_ctrl wants a non-const pointer as last argument,
    358             // but let's avoid a copy into a temporary array
    359             if (!q_SSL_CTX_ctrl(sslContext->ctx,
    360                                 SSL_CTRL_SET_CURVES,
    361                                 qcurves.size(),
    362                                 const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())))) {
    363                 sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
    364                 sslContext->errorCode = QSslError::UnspecifiedError;
    365             }
    366         } else
    367 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
    368         {
    369             // specific curves requested, but not possible to set -> error
    370             sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
    371             sslContext->errorCode = QSslError::UnspecifiedError;
    372         }
    373     }
    374 }
    375 
    37673QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
    37774{
    37875    QSslContext *sslContext = new QSslContext();
    SSL* QSslContext::createSsl() 
    463160        m_npnContext.len = m_supportedNPNVersions.count();
    464161        m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
    465162#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    466         if (q_SSLeay() >= 0x10002000L) {
     163        if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
    467164            // Callback's type has a parameter 'const unsigned char ** out'
    468165            // since it was introduced in 1.0.2. Internally, OpenSSL's own code
    469166            // (tests/examples) cast it to unsigned char * (since it's 'out').
    bool QSslContext::cacheSession(SSL* ssl) 
    508205            unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
    509206            if (!q_i2d_SSL_SESSION(session, &data))
    510207                qCWarning(lcSsl, "could not store persistent version of SSL session");
    511             m_sessionTicketLifeTimeHint = session->tlsext_tick_lifetime_hint;
     208            m_sessionTicketLifeTimeHint = q_SSL_SESSION_get_ticket_lifetime_hint(session);
    512209        }
    513210    }
    514211
  • new file qtbase/src/network/ssl/qsslcontext_openssl11.cpp

    diff --git a/qtbase/src/network/ssl/qsslcontext_openssl11.cpp b/qtbase/src/network/ssl/qsslcontext_openssl11.cpp
    new file mode 100644
    index 0000000000000000000000000000000000000000..787b6ae3f512ca905c5dd8edcb86a04e322b9e76
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
     5** Copyright (C) 2014 Governikus GmbH & Co. KG.
     6** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
     7** Contact: https://www.qt.io/licensing/
     8**
     9** This file is part of the QtNetwork module of the Qt Toolkit.
     10**
     11** $QT_BEGIN_LICENSE:LGPL$
     12** Commercial License Usage
     13** Licensees holding valid commercial Qt licenses may use this file in
     14** accordance with the commercial license agreement provided with the
     15** Software or, alternatively, in accordance with the terms contained in
     16** a written agreement between you and The Qt Company. For licensing terms
     17** and conditions see https://www.qt.io/terms-conditions. For further
     18** information use the contact form at https://www.qt.io/contact-us.
     19**
     20** GNU Lesser General Public License Usage
     21** Alternatively, this file may be used under the terms of the GNU Lesser
     22** General Public License version 3 as published by the Free Software
     23** Foundation and appearing in the file LICENSE.LGPL3 included in the
     24** packaging of this file. Please review the following information to
     25** ensure the GNU Lesser General Public License version 3 requirements
     26** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     27**
     28** GNU General Public License Usage
     29** Alternatively, this file may be used under the terms of the GNU
     30** General Public License version 2.0 or (at your option) the GNU General
     31** Public license version 3 or any later version approved by the KDE Free
     32** Qt Foundation. The licenses are as published by the Free Software
     33** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     34** included in the packaging of this file. Please review the following
     35** information to ensure the GNU General Public License requirements will
     36** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     37** https://www.gnu.org/licenses/gpl-3.0.html.
     38**
     39** $QT_END_LICENSE$
     40**
     41****************************************************************************/
     42
     43
     44#include <QtNetwork/qsslsocket.h>
     45#include <QtNetwork/qssldiffiehellmanparameters.h>
     46
     47#include "private/qssl_p.h"
     48#include "private/qsslcontext_openssl_p.h"
     49#include "private/qsslsocket_p.h"
     50#include "private/qsslsocket_openssl_p.h"
     51#include "private/qsslsocket_openssl_symbols_p.h"
     52#include "private/qssldiffiehellmanparameters_p.h"
     53
     54#include <vector>
     55
     56QT_BEGIN_NAMESPACE
     57
     58// defined in qsslsocket_openssl.cpp:
     59extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
     60extern QString getErrorsFromOpenSsl();
     61
     62static inline QString msgErrorSettingEllipticCurves(const QString &why)
     63{
     64    return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
     65}
     66
     67// static
     68void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
     69{
     70    sslContext->sslConfiguration = configuration;
     71    sslContext->errorCode = QSslError::NoError;
     72
     73    bool client = (mode == QSslSocket::SslClientMode);
     74
     75    bool reinitialized = false;
     76    bool unsupportedProtocol = false;
     77init_context:
     78    if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) {
     79        // SSL 2 is no longer supported, but chosen deliberately -> error
     80        sslContext->ctx = nullptr;
     81        unsupportedProtocol = true;
     82    } else {
     83        // The ssl options will actually control the supported methods
     84        sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method());
     85    }
     86
     87    if (!sslContext->ctx) {
     88        // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
     89        // by re-initializing the library.
     90        if (!reinitialized) {
     91            reinitialized = true;
     92            if (q_OPENSSL_init_ssl(0, nullptr) == 1)
     93                goto init_context;
     94        }
     95
     96        sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
     97            unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
     98        );
     99        sslContext->errorCode = QSslError::UnspecifiedError;
     100        return;
     101    }
     102
     103    // Enable bug workarounds.
     104    long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
     105    q_SSL_CTX_set_options(sslContext->ctx, options);
     106
     107    // Tell OpenSSL to release memory early
     108    // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
     109    q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
     110
     111    // Initialize ciphers
     112    QByteArray cipherString;
     113    bool first = true;
     114    QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
     115    if (ciphers.isEmpty())
     116        ciphers = QSslSocketPrivate::defaultCiphers();
     117    for (const QSslCipher &cipher : qAsConst(ciphers)) {
     118        if (first)
     119            first = false;
     120        else
     121            cipherString.append(':');
     122        cipherString.append(cipher.name().toLatin1());
     123    }
     124
     125    if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
     126        sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     127        sslContext->errorCode = QSslError::UnspecifiedError;
     128        return;
     129    }
     130
     131    const QDateTime now = QDateTime::currentDateTimeUtc();
     132
     133    // Add all our CAs to this store.
     134    const auto caCertificates = sslContext->sslConfiguration.caCertificates();
     135    for (const QSslCertificate &caCertificate : caCertificates) {
     136        // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
     137        //
     138        // If several CA certificates matching the name, key identifier, and
     139        // serial number condition are available, only the first one will be
     140        // examined. This may lead to unexpected results if the same CA
     141        // certificate is available with different expiration dates. If a
     142        // ``certificate expired'' verification error occurs, no other
     143        // certificate will be searched. Make sure to not have expired
     144        // certificates mixed with valid ones.
     145        //
     146        // See also: QSslSocketBackendPrivate::verify()
     147        if (caCertificate.expiryDate() >= now) {
     148            q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
     149        }
     150    }
     151
     152    if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
     153        // tell OpenSSL the directories where to look up the root certs on demand
     154        const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
     155        for (const QByteArray &unixDir : unixDirs)
     156            q_SSL_CTX_load_verify_locations(sslContext->ctx, nullptr, unixDir.constData());
     157    }
     158
     159    if (!sslContext->sslConfiguration.localCertificate().isNull()) {
     160        // Require a private key as well.
     161        if (sslContext->sslConfiguration.privateKey().isNull()) {
     162            sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     163            sslContext->errorCode = QSslError::UnspecifiedError;
     164            return;
     165        }
     166
     167        // Load certificate
     168        if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
     169            sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     170            sslContext->errorCode = QSslError::UnspecifiedError;
     171            return;
     172        }
     173
     174        if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
     175            sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
     176        } else {
     177            // Load private key
     178            sslContext->pkey = q_EVP_PKEY_new();
     179            // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
     180            // this lead to a memory leak. Now we use the *_set1_* functions which do not
     181            // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
     182            if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
     183                q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
     184            else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
     185                q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
     186#ifndef OPENSSL_NO_EC
     187            else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
     188                q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
     189#endif
     190        }
     191
     192        if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
     193            sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     194            sslContext->errorCode = QSslError::UnspecifiedError;
     195            return;
     196        }
     197        if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
     198            sslContext->pkey = nullptr; // Don't free the private key, it belongs to QSslKey
     199
     200        // Check if the certificate matches the private key.
     201        if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
     202            sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     203            sslContext->errorCode = QSslError::UnspecifiedError;
     204            return;
     205        }
     206
     207        // If we have any intermediate certificates then we need to add them to our chain
     208        bool first = true;
     209        for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
     210            if (first) {
     211                first = false;
     212                continue;
     213            }
     214            q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
     215                           q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
     216        }
     217    }
     218
     219    // Initialize peer verification.
     220    if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
     221        q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr);
     222    } else {
     223        q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
     224    }
     225
     226    // Set verification depth.
     227    if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
     228        q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
     229
     230    // set persisted session if the user set it
     231    if (!configuration.sessionTicket().isEmpty())
     232        sslContext->setSessionASN1(configuration.sessionTicket());
     233
     234    // Set temp DH params
     235    QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters();
     236
     237    if (!dhparams.isValid()) {
     238        sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid");
     239        sslContext->errorCode = QSslError::UnspecifiedError;
     240        return;
     241    }
     242
     243    if (!dhparams.isEmpty()) {
     244        const QByteArray &params = dhparams.d->derData;
     245        const char *ptr = params.constData();
     246        DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
     247        if (dh == NULL)
     248            qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form");
     249        q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
     250        q_DH_free(dh);
     251    }
     252
     253#ifndef OPENSSL_NO_PSK
     254    if (!client)
     255        q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
     256#endif // !OPENSSL_NO_PSK
     257
     258    const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
     259    if (!qcurves.isEmpty()) {
     260#ifdef OPENSSL_NO_EC
     261        sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version with disabled elliptic curves"));
     262        sslContext->errorCode = QSslError::UnspecifiedError;
     263#else
     264        // Set the curves to be used.
     265        std::vector<int> curves;
     266        curves.reserve(qcurves.size());
     267        for (const auto &sslCurve : qcurves)
     268            curves.push_back(sslCurve.id);
     269        if (!q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_CURVES, long(curves.size()), &curves[0])) {
     270            sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     271            sslContext->errorCode = QSslError::UnspecifiedError;
     272        }
     273#endif
     274    }
     275}
     276
     277QT_END_NAMESPACE
  • new file qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp

    diff --git a/qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp b/qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp
    new file mode 100644
    index 0000000000000000000000000000000000000000..9c01c2f2dccf9aa23258009eeee5072657aa9b3e
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
     5** Copyright (C) 2014 Governikus GmbH & Co. KG.
     6** Contact: https://www.qt.io/licensing/
     7**
     8** This file is part of the QtNetwork module of the Qt Toolkit.
     9**
     10** $QT_BEGIN_LICENSE:LGPL$
     11** Commercial License Usage
     12** Licensees holding valid commercial Qt licenses may use this file in
     13** accordance with the commercial license agreement provided with the
     14** Software or, alternatively, in accordance with the terms contained in
     15** a written agreement between you and The Qt Company. For licensing terms
     16** and conditions see https://www.qt.io/terms-conditions. For further
     17** information use the contact form at https://www.qt.io/contact-us.
     18**
     19** GNU Lesser General Public License Usage
     20** Alternatively, this file may be used under the terms of the GNU Lesser
     21** General Public License version 3 as published by the Free Software
     22** Foundation and appearing in the file LICENSE.LGPL3 included in the
     23** packaging of this file. Please review the following information to
     24** ensure the GNU Lesser General Public License version 3 requirements
     25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     26**
     27** GNU General Public License Usage
     28** Alternatively, this file may be used under the terms of the GNU
     29** General Public License version 2.0 or (at your option) the GNU General
     30** Public license version 3 or any later version approved by the KDE Free
     31** Qt Foundation. The licenses are as published by the Free Software
     32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     33** included in the packaging of this file. Please review the following
     34** information to ensure the GNU General Public License requirements will
     35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     36** https://www.gnu.org/licenses/gpl-3.0.html.
     37**
     38** $QT_END_LICENSE$
     39**
     40****************************************************************************/
     41
     42
     43#include <QtNetwork/qsslsocket.h>
     44#include <QtNetwork/qssldiffiehellmanparameters.h>
     45
     46#include "private/qssl_p.h"
     47#include "private/qsslcontext_openssl_p.h"
     48#include "private/qsslsocket_p.h"
     49#include "private/qsslsocket_openssl_p.h"
     50#include "private/qsslsocket_openssl_symbols_p.h"
     51#include "private/qssldiffiehellmanparameters_p.h"
     52
     53QT_BEGIN_NAMESPACE
     54
     55// defined in qsslsocket_openssl.cpp:
     56extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
     57extern QString getErrorsFromOpenSsl();
     58
     59static inline QString msgErrorSettingEllipticCurves(const QString &why)
     60{
     61    return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why);
     62}
     63
     64// static
     65void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading)
     66{
     67    sslContext->sslConfiguration = configuration;
     68    sslContext->errorCode = QSslError::NoError;
     69
     70    bool client = (mode == QSslSocket::SslClientMode);
     71
     72    bool reinitialized = false;
     73    bool unsupportedProtocol = false;
     74init_context:
     75    switch (sslContext->sslConfiguration.protocol()) {
     76    case QSsl::SslV2:
     77#ifndef OPENSSL_NO_SSL2
     78        sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
     79#else
     80        // SSL 2 not supported by the system, but chosen deliberately -> error
     81        sslContext->ctx = 0;
     82        unsupportedProtocol = true;
     83#endif
     84        break;
     85    case QSsl::SslV3:
     86#ifndef OPENSSL_NO_SSL3_METHOD
     87        sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
     88#else
     89        // SSL 3 not supported by the system, but chosen deliberately -> error
     90        sslContext->ctx = 0;
     91        unsupportedProtocol = true;
     92#endif
     93        break;
     94    case QSsl::SecureProtocols:
     95        // SSLv2 and SSLv3 will be disabled by SSL options
     96        // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32.
     97    case QSsl::TlsV1SslV3:
     98        // SSLv2 will will be disabled by SSL options
     99    case QSsl::AnyProtocol:
     100    default:
     101        sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
     102        break;
     103    case QSsl::TlsV1_0:
     104        sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
     105        break;
     106    case QSsl::TlsV1_1:
     107#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     108        sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
     109#else
     110        // TLS 1.1 not supported by the system, but chosen deliberately -> error
     111        sslContext->ctx = 0;
     112        unsupportedProtocol = true;
     113#endif
     114        break;
     115    case QSsl::TlsV1_2:
     116#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     117        sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
     118#else
     119        // TLS 1.2 not supported by the system, but chosen deliberately -> error
     120        sslContext->ctx = 0;
     121        unsupportedProtocol = true;
     122#endif
     123        break;
     124    case QSsl::TlsV1_0OrLater:
     125        // Specific protocols will be specified via SSL options.
     126        sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
     127        break;
     128    case QSsl::TlsV1_1OrLater:
     129    case QSsl::TlsV1_2OrLater:
     130#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     131        // Specific protocols will be specified via SSL options.
     132        sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
     133#else
     134        // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error
     135        sslContext->ctx = 0;
     136        unsupportedProtocol = true;
     137#endif
     138        break;
     139    }
     140
     141    if (!sslContext->ctx) {
     142        // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them
     143        // by re-initializing the library.
     144        if (!reinitialized) {
     145            reinitialized = true;
     146            if (q_SSL_library_init() == 1)
     147                goto init_context;
     148        }
     149
     150        sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(
     151            unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl()
     152        );
     153        sslContext->errorCode = QSslError::UnspecifiedError;
     154        return;
     155    }
     156
     157    // Enable bug workarounds.
     158    long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
     159    q_SSL_CTX_set_options(sslContext->ctx, options);
     160
     161#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     162    // Tell OpenSSL to release memory early
     163    // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html
     164    if (q_SSLeay() >= 0x10000000L)
     165        q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS);
     166#endif
     167
     168    // Initialize ciphers
     169    QByteArray cipherString;
     170    bool first = true;
     171    QList<QSslCipher> ciphers = sslContext->sslConfiguration.ciphers();
     172    if (ciphers.isEmpty())
     173        ciphers = QSslSocketPrivate::defaultCiphers();
     174    for (const QSslCipher &cipher : qAsConst(ciphers)) {
     175        if (first)
     176            first = false;
     177        else
     178            cipherString.append(':');
     179        cipherString.append(cipher.name().toLatin1());
     180    }
     181
     182    if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) {
     183        sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     184        sslContext->errorCode = QSslError::UnspecifiedError;
     185        return;
     186    }
     187
     188    const QDateTime now = QDateTime::currentDateTimeUtc();
     189
     190    // Add all our CAs to this store.
     191    const auto caCertificates = sslContext->sslConfiguration.caCertificates();
     192    for (const QSslCertificate &caCertificate : caCertificates) {
     193        // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html:
     194        //
     195        // If several CA certificates matching the name, key identifier, and
     196        // serial number condition are available, only the first one will be
     197        // examined. This may lead to unexpected results if the same CA
     198        // certificate is available with different expiration dates. If a
     199        // ``certificate expired'' verification error occurs, no other
     200        // certificate will be searched. Make sure to not have expired
     201        // certificates mixed with valid ones.
     202        //
     203        // See also: QSslSocketBackendPrivate::verify()
     204        if (caCertificate.expiryDate() >= now) {
     205            q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle());
     206        }
     207    }
     208
     209    if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
     210        // tell OpenSSL the directories where to look up the root certs on demand
     211        const QList<QByteArray> unixDirs = QSslSocketPrivate::unixRootCertDirectories();
     212        for (const QByteArray &unixDir : unixDirs)
     213            q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDir.constData());
     214    }
     215
     216    if (!sslContext->sslConfiguration.localCertificate().isNull()) {
     217        // Require a private key as well.
     218        if (sslContext->sslConfiguration.privateKey().isNull()) {
     219            sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     220            sslContext->errorCode = QSslError::UnspecifiedError;
     221            return;
     222        }
     223
     224        // Load certificate
     225        if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) {
     226            sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     227            sslContext->errorCode = QSslError::UnspecifiedError;
     228            return;
     229        }
     230
     231        if (configuration.d->privateKey.algorithm() == QSsl::Opaque) {
     232            sslContext->pkey = reinterpret_cast<EVP_PKEY *>(configuration.d->privateKey.handle());
     233        } else {
     234            // Load private key
     235            sslContext->pkey = q_EVP_PKEY_new();
     236            // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
     237            // this lead to a memory leak. Now we use the *_set1_* functions which do not
     238            // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
     239            if (configuration.d->privateKey.algorithm() == QSsl::Rsa)
     240                q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast<RSA *>(configuration.d->privateKey.handle()));
     241            else if (configuration.d->privateKey.algorithm() == QSsl::Dsa)
     242                q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast<DSA *>(configuration.d->privateKey.handle()));
     243#ifndef OPENSSL_NO_EC
     244            else if (configuration.d->privateKey.algorithm() == QSsl::Ec)
     245                q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast<EC_KEY *>(configuration.d->privateKey.handle()));
     246#endif
     247        }
     248
     249        if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) {
     250            sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     251            sslContext->errorCode = QSslError::UnspecifiedError;
     252            return;
     253        }
     254        if (configuration.d->privateKey.algorithm() == QSsl::Opaque)
     255            sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey
     256
     257        // Check if the certificate matches the private key.
     258        if (!q_SSL_CTX_check_private_key(sslContext->ctx)) {
     259            sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     260            sslContext->errorCode = QSslError::UnspecifiedError;
     261            return;
     262        }
     263
     264        // If we have any intermediate certificates then we need to add them to our chain
     265        bool first = true;
     266        for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) {
     267            if (first) {
     268                first = false;
     269                continue;
     270            }
     271            q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
     272                           q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
     273        }
     274    }
     275
     276    // Initialize peer verification.
     277    if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) {
     278        q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0);
     279    } else {
     280        q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback);
     281    }
     282
     283    // Set verification depth.
     284    if (sslContext->sslConfiguration.peerVerifyDepth() != 0)
     285        q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth());
     286
     287    // set persisted session if the user set it
     288    if (!configuration.sessionTicket().isEmpty())
     289        sslContext->setSessionASN1(configuration.sessionTicket());
     290
     291    // Set temp DH params
     292    QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters();
     293
     294    if (!dhparams.isValid()) {
     295        sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid");
     296        sslContext->errorCode = QSslError::UnspecifiedError;
     297        return;
     298    }
     299
     300    if (!dhparams.isEmpty()) {
     301        const QByteArray &params = dhparams.d->derData;
     302        const char *ptr = params.constData();
     303        DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length());
     304        if (dh == NULL)
     305            qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form");
     306        q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
     307        q_DH_free(dh);
     308    }
     309
     310#ifndef OPENSSL_NO_EC
     311#if OPENSSL_VERSION_NUMBER >= 0x10002000L
     312    if (q_SSLeay() >= 0x10002000L) {
     313        q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
     314    } else
     315#endif
     316    {
     317        // Set temp ECDH params
     318        EC_KEY *ecdh = 0;
     319        ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
     320        q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh);
     321        q_EC_KEY_free(ecdh);
     322    }
     323#endif // OPENSSL_NO_EC
     324
     325#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
     326    if (!client)
     327        q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData());
     328#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
     329
     330    const QVector<QSslEllipticCurve> qcurves = sslContext->sslConfiguration.ellipticCurves();
     331    if (!qcurves.isEmpty()) {
     332#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
     333        // Set the curves to be used
     334        if (q_SSLeay() >= 0x10002000L) {
     335            // SSL_CTX_ctrl wants a non-const pointer as last argument,
     336            // but let's avoid a copy into a temporary array
     337            if (!q_SSL_CTX_ctrl(sslContext->ctx,
     338                                SSL_CTRL_SET_CURVES,
     339                                qcurves.size(),
     340                                const_cast<int *>(reinterpret_cast<const int *>(qcurves.data())))) {
     341                sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
     342                sslContext->errorCode = QSslError::UnspecifiedError;
     343            }
     344        } else
     345#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC)
     346        {
     347            // specific curves requested, but not possible to set -> error
     348            sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
     349            sslContext->errorCode = QSslError::UnspecifiedError;
     350        }
     351    }
     352}
     353
     354QT_END_NAMESPACE
  • qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp
    index 90687b05c53ede8b4d8f72fc8fb5af6cf45642f7..5ebad822f1a4ecf5fe2b12b324066293840db8f7 100644
    a b  
    11/****************************************************************************
    22**
    33** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
     4** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
    45** Contact: https://www.qt.io/licensing/
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
     
    5051#include <QtCore/qdebug.h>
    5152#endif
    5253
    53 // For q_BN_is_word.
    5454#include <openssl/bn.h>
     55#include <openssl/dh.h>
    5556
    5657QT_BEGIN_NAMESPACE
    5758
    static bool isSafeDH(DH *dh) 
    6263
    6364    QSslSocketPrivate::ensureInitialized();
    6465
    65     // Mark p < 1024 bits as unsafe.
    66     if (q_BN_num_bits(dh->p) < 1024) {
    67         return false;
    68     }
    69 
    70     if (q_DH_check(dh, &status) != 1)
    71         return false;
    7266
    7367    // From https://wiki.openssl.org/index.php/Diffie-Hellman_parameters:
    7468    //
    static bool isSafeDH(DH *dh) 
    8175    //     Without the test, the IETF parameters would
    8276    //     fail validation. For details, see Diffie-Hellman
    8377    //     Parameter Check (when g = 2, must p mod 24 == 11?).
     78#if QT_CONFIG(opensslv11)
     79    // Mark p < 1024 bits as unsafe.
     80    if (q_DH_bits(dh) < 1024)
     81        return false;
     82
     83    if (q_DH_check(dh, &status) != 1)
     84        return false;
     85
     86    const BIGNUM *p = nullptr;
     87    const BIGNUM *q = nullptr;
     88    const BIGNUM *g = nullptr;
     89    q_DH_get0_pqg(dh, &p, &q, &g);
     90
     91    if (q_BN_is_word(const_cast<BIGNUM *>(g), DH_GENERATOR_2)) {
     92        long residue = q_BN_mod_word(p, 24);
     93        if (residue == 11 || residue == 23)
     94            status &= ~DH_NOT_SUITABLE_GENERATOR;
     95    }
     96
     97#else
     98    // Mark p < 1024 bits as unsafe.
     99    if (q_BN_num_bits(dh->p) < 1024)
     100        return false;
     101
     102    if (q_DH_check(dh, &status) != 1)
     103        return false;
     104
    84105    if (q_BN_is_word(dh->g, DH_GENERATOR_2)) {
    85106        long residue = q_BN_mod_word(dh->p, 24);
    86107        if (residue == 11 || residue == 23)
    87108            status &= ~DH_NOT_SUITABLE_GENERATOR;
    88109    }
     110#endif
    89111
    90112    bad |= DH_CHECK_P_NOT_PRIME;
    91113    bad |= DH_CHECK_P_NOT_SAFE_PRIME;
  • qtbase/src/network/ssl/qsslellipticcurve.h

    diff --git a/qtbase/src/network/ssl/qsslellipticcurve.h b/qtbase/src/network/ssl/qsslellipticcurve.h
    index 231566063ebbfcaabd3873fa8913214cdac4b934..57dda19badd795f0833acbb19cc3727ba2d57615 100644
    a b private: 
    8080    friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW;
    8181    friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW;
    8282
     83    friend class QSslContext;
    8384    friend class QSslSocketPrivate;
    8485    friend class QSslSocketBackendPrivate;
    8586};
  • qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp b/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp
    index e18197b703ed8bfc45947f5675a69078433bedee..8cd14837f0fe9efacf9a2d75b89f881eebf5dfd6 100644
    a b  
    11/****************************************************************************
    22**
    33** Copyright (C) 2014 Governikus GmbH & Co. KG.
     4** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
    45** Contact: https://www.qt.io/licensing/
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
    QSslEllipticCurve QSslEllipticCurve::fromShortName(const QString &name) 
    7879    QSslEllipticCurve result;
    7980
    8081#ifndef OPENSSL_NO_EC
    81     const QByteArray curveNameLatin1 = name.toLatin1();
    8282
     83    const QByteArray curveNameLatin1 = name.toLatin1();
    8384    int nid = q_OBJ_sn2nid(curveNameLatin1.data());
    8485
    8586#if OPENSSL_VERSION_NUMBER >= 0x10002000L
    86     if (nid == 0 && q_SSLeay() >= 0x10002000L)
     87    if (nid == 0 && QSslSocket::sslLibraryVersionNumber() >= 0x10002000L)
    8788        nid = q_EC_curve_nist2nid(curveNameLatin1.data());
    8889#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
    8990
    9091    result.id = nid;
    91 #endif
     92
     93#endif // !OPENSSL_NO_EC
    9294
    9395    return result;
    9496}
  • qtbase/src/network/ssl/qsslkey_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qsslkey_openssl.cpp b/qtbase/src/network/ssl/qsslkey_openssl.cpp
    index 26119023d14dd55393770352d30d7f2c0ba1838b..aa81b735b98234bf88ca3db0841914281c8570d8 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
    45** Contact: https://www.qt.io/licensing/
    56**
    67** This file is part of the QtNetwork module of the Qt Toolkit.
    bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) 
    8788    if (pkey == nullptr)
    8889        return false;
    8990
    90     if (pkey->type == EVP_PKEY_RSA) {
     91#if QT_CONFIG(opensslv11)
     92    const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey));
     93#else
     94    const int keyType = pkey->type;
     95#endif
     96    if (keyType == EVP_PKEY_RSA) {
    9197        isNull = false;
    9298        algorithm = QSsl::Rsa;
    9399        type = QSsl::PrivateKey;
    94 
    95         rsa = q_RSA_new();
    96         memcpy(rsa, q_EVP_PKEY_get1_RSA(pkey), sizeof(RSA));
    97 
     100        rsa = q_EVP_PKEY_get1_RSA(pkey);
    98101        return true;
    99     }
    100     else if (pkey->type == EVP_PKEY_DSA) {
     102    } else if (keyType == EVP_PKEY_DSA) {
    101103        isNull = false;
    102104        algorithm = QSsl::Dsa;
    103105        type = QSsl::PrivateKey;
    104 
    105         dsa = q_DSA_new();
    106         memcpy(dsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA));
    107 
     106        dsa = q_EVP_PKEY_get1_DSA(pkey);
    108107        return true;
    109108    }
    110109#ifndef OPENSSL_NO_EC
    111     else if (pkey->type == EVP_PKEY_EC) {
     110    else if (keyType == EVP_PKEY_EC) {
    112111        isNull = false;
    113112        algorithm = QSsl::Ec;
    114113        type = QSsl::PrivateKey;
    115         ec = q_EC_KEY_dup(q_EVP_PKEY_get1_EC_KEY(pkey));
    116 
     114        ec = q_EVP_PKEY_get1_EC_KEY(pkey);
    117115        return true;
    118116    }
    119117#endif
    int QSslKeyPrivate::length() const 
    181179        return -1;
    182180
    183181    switch (algorithm) {
    184         case QSsl::Rsa: return q_BN_num_bits(rsa->n);
    185         case QSsl::Dsa: return q_BN_num_bits(dsa->p);
     182        case QSsl::Rsa: return q_RSA_bits(rsa);
     183        case QSsl::Dsa: return q_DSA_bits(dsa);
    186184#ifndef OPENSSL_NO_EC
    187185        case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec));
    188186#endif
    Qt::HANDLE QSslKeyPrivate::handle() const 
    276274
    277275static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv, int enc)
    278276{
    279     EVP_CIPHER_CTX ctx;
     277#if QT_CONFIG(opensslv11)
     278    EVP_CIPHER_CTX *ctx = q_EVP_CIPHER_CTX_new();
     279#else
     280    EVP_CIPHER_CTX evpCipherContext;
     281    EVP_CIPHER_CTX *ctx = &evpCipherContext;
     282#endif
     283
    280284    const EVP_CIPHER* type = 0;
    281285    int i = 0, len = 0;
    282286
    static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, 
    294298
    295299    QByteArray output;
    296300    output.resize(data.size() + EVP_MAX_BLOCK_LENGTH);
    297     q_EVP_CIPHER_CTX_init(&ctx);
    298     q_EVP_CipherInit(&ctx, type, NULL, NULL, enc);
    299     q_EVP_CIPHER_CTX_set_key_length(&ctx, key.size());
     301
     302#if QT_CONFIG(opensslv11)
     303    q_EVP_CIPHER_CTX_reset(ctx);
     304#else
     305    q_EVP_CIPHER_CTX_init(ctx);
     306#endif
     307
     308    q_EVP_CipherInit(ctx, type, NULL, NULL, enc);
     309    q_EVP_CIPHER_CTX_set_key_length(ctx, key.size());
    300310    if (cipher == QSslKeyPrivate::Rc2Cbc)
    301         q_EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL);
    302     q_EVP_CipherInit(&ctx, NULL,
     311        q_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL);
     312
     313#if QT_CONFIG(opensslv11)
     314    // EVP_CipherInit in 1.1 resets the context thus making the calls above useless.
     315    // We call EVP_CipherInit_ex instead.
     316    q_EVP_CipherInit_ex(ctx, nullptr, nullptr,
     317                        reinterpret_cast<const unsigned char *>(key.constData()),
     318                        reinterpret_cast<const unsigned char *>(iv.constData()),
     319                        enc);
     320#else
     321    q_EVP_CipherInit(ctx, NULL,
    303322        reinterpret_cast<const unsigned char *>(key.constData()),
    304323        reinterpret_cast<const unsigned char *>(iv.constData()), enc);
    305     q_EVP_CipherUpdate(&ctx,
     324#endif // opensslv11
     325
     326    q_EVP_CipherUpdate(ctx,
    306327        reinterpret_cast<unsigned char *>(output.data()), &len,
    307328        reinterpret_cast<const unsigned char *>(data.constData()), data.size());
    308     q_EVP_CipherFinal(&ctx,
     329    q_EVP_CipherFinal(ctx,
    309330        reinterpret_cast<unsigned char *>(output.data()) + len, &i);
    310331    len += i;
    311     q_EVP_CIPHER_CTX_cleanup(&ctx);
     332
     333#if QT_CONFIG(opensslv11)
     334    q_EVP_CIPHER_CTX_reset(ctx);
     335    q_EVP_CIPHER_CTX_free(ctx);
     336#else
     337    q_EVP_CIPHER_CTX_cleanup(ctx);
     338#endif
    312339
    313340    return output.left(len);
    314341}
  • qtbase/src/network/ssl/qsslsocket_openssl.cpp

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp
    index f5b493897ea0509483341c92c594626aa8ed4ca4..14cef1949a18c17ffdad3752986ec1f14a597d1f 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
    44** Copyright (C) 2014 Governikus GmbH & Co. KG
    55** Contact: https://www.qt.io/licensing/
    66**
    bool QSslSocketPrivate::s_loadRootCertsOnDemand = false; 
    9797int QSslSocketBackendPrivate::s_indexForSSLExtraData = -1;
    9898#endif
    9999
    100 /* \internal
    101 
    102     From OpenSSL's thread(3) manual page:
    103 
    104     OpenSSL can safely be used in multi-threaded applications provided that at
    105     least two callback functions are set.
    106 
    107     locking_function(int mode, int n, const char *file, int line) is needed to
    108     perform locking on shared data structures.  (Note that OpenSSL uses a
    109     number of global data structures that will be implicitly shared
    110     whenever multiple threads use OpenSSL.)  Multi-threaded
    111     applications will crash at random if it is not set.  ...
    112     ...
    113     id_function(void) is a function that returns a thread ID. It is not
    114     needed on Windows nor on platforms where getpid() returns a different
    115     ID for each thread (most notably Linux)
    116 */
    117 class QOpenSslLocks
    118 {
    119 public:
    120     inline QOpenSslLocks()
    121         : initLocker(QMutex::Recursive),
    122           locksLocker(QMutex::Recursive)
    123     {
    124         QMutexLocker locker(&locksLocker);
    125         int numLocks = q_CRYPTO_num_locks();
    126         locks = new QMutex *[numLocks];
    127         memset(locks, 0, numLocks * sizeof(QMutex *));
    128     }
    129     inline ~QOpenSslLocks()
    130     {
    131         QMutexLocker locker(&locksLocker);
    132         for (int i = 0; i < q_CRYPTO_num_locks(); ++i)
    133             delete locks[i];
    134         delete [] locks;
    135 
    136         QSslSocketPrivate::deinitialize();
    137     }
    138     inline QMutex *lock(int num)
    139     {
    140         QMutexLocker locker(&locksLocker);
    141         QMutex *tmp = locks[num];
    142         if (!tmp)
    143             tmp = locks[num] = new QMutex(QMutex::Recursive);
    144         return tmp;
    145     }
    146 
    147     QMutex *globalLock()
    148     {
    149         return &locksLocker;
    150     }
    151 
    152     QMutex *initLock()
    153     {
    154         return &initLocker;
    155     }
    156 
    157 private:
    158     QMutex initLocker;
    159     QMutex locksLocker;
    160     QMutex **locks;
    161 };
    162 Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
    163 
    164100QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
    165101{
    166102    QString errorString;
    QString QSslSocketBackendPrivate::getErrorsFromOpenSsl() 
    175111}
    176112
    177113extern "C" {
    178 static void locking_function(int mode, int lockNumber, const char *, int)
    179 {
    180     QMutex *mutex = openssl_locks()->lock(lockNumber);
    181 
    182     // Lock or unlock it
    183     if (mode & CRYPTO_LOCK)
    184         mutex->lock();
    185     else
    186         mutex->unlock();
    187 }
    188 static unsigned long id_function()
    189 {
    190     return (quintptr)QThread::currentThreadId();
    191 }
    192114
    193115#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
    194116static unsigned int q_ssl_psk_client_callback(SSL *ssl,
    QSslSocketBackendPrivate::~QSslSocketBackendPrivate() 
    227149    destroySslContext();
    228150}
    229151
    230 QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher)
     152QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher)
    231153{
    232154    QSslCipher ciph;
    233155
    QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *ciph 
    268190}
    269191
    270192// static
    271 inline QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx) {
     193inline QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx)
     194{
    272195    QSslErrorEntry result = {
    273196        q_X509_STORE_CTX_get_error(ctx),
    274197        q_X509_STORE_CTX_get_error_depth(ctx)
    struct QSslErrorList 
    283206    QMutex mutex;
    284207    QVector<QSslErrorEntry> errors;
    285208};
     209
    286210Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
    287211
    288212int q_X509Callback(int ok, X509_STORE_CTX *ctx)
    int q_X509Callback(int ok, X509_STORE_CTX *ctx) 
    312236        }
    313237#endif
    314238    }
    315     // Always return OK to allow verification to continue. We're handle the
     239    // Always return OK to allow verification to continue. We handle the
    316240    // errors gracefully after collecting all errors, after verification has
    317241    // completed.
    318242    return 1;
    bool QSslSocketBackendPrivate::initSslContext() 
    397321    if (configuration.protocol != QSsl::SslV2 &&
    398322        configuration.protocol != QSsl::SslV3 &&
    399323        configuration.protocol != QSsl::UnknownProtocol &&
    400         mode == QSslSocket::SslClientMode && q_SSLeay() >= 0x00090806fL) {
     324        mode == QSslSocket::SslClientMode && QSslSocket::sslLibraryVersionNumber() >= 0x00090806fL) {
    401325        // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
    402326        QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
    403327        if (tlsHostName.isEmpty())
    bool QSslSocketBackendPrivate::initSslContext() 
    438362
    439363#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    440364    // Save a pointer to this object into the SSL structure.
    441     if (q_SSLeay() >= 0x10001000L)
     365    if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L)
    442366        q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
    443367#endif
    444368
    445369#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
    446370    // Set the client callback for PSK
    447     if (q_SSLeay() >= 0x10001000L) {
     371    if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L) {
    448372        if (mode == QSslSocket::SslClientMode)
    449373            q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback);
    450374        else if (mode == QSslSocket::SslServerMode)
    void QSslSocketBackendPrivate::destroySslContext() 
    464388    sslContextPointer.clear();
    465389}
    466390
    467 /*!
    468     \internal
    469 */
    470 void QSslSocketPrivate::deinitialize()
    471 {
    472     q_CRYPTO_set_id_callback(0);
    473     q_CRYPTO_set_locking_callback(0);
    474     q_ERR_free_strings();
    475 }
    476 
    477391/*!
    478392    \internal
    479393
    bool QSslSocketPrivate::supportsSsl() 
    486400    return ensureLibraryLoaded();
    487401}
    488402
    489 bool QSslSocketPrivate::ensureLibraryLoaded()
    490 {
    491     if (!q_resolveOpenSslSymbols())
    492         return false;
    493 
    494     // Check if the library itself needs to be initialized.
    495     QMutexLocker locker(openssl_locks()->initLock());
    496 
    497     if (!s_libraryLoaded) {
    498         s_libraryLoaded = true;
    499 
    500         // Initialize OpenSSL.
    501         q_CRYPTO_set_id_callback(id_function);
    502         q_CRYPTO_set_locking_callback(locking_function);
    503         if (q_SSL_library_init() != 1)
    504             return false;
    505         q_SSL_load_error_strings();
    506         q_OpenSSL_add_all_algorithms();
    507 
    508 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    509         if (q_SSLeay() >= 0x10001000L)
    510             QSslSocketBackendPrivate::s_indexForSSLExtraData = q_SSL_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
    511 #endif
    512 
    513         // Initialize OpenSSL's random seed.
    514         if (!q_RAND_status()) {
    515             qWarning("Random number generator not seeded, disabling SSL support");
    516             return false;
    517         }
    518     }
    519     return true;
    520 }
    521 
    522 void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
    523 {
    524     QMutexLocker locker(openssl_locks()->initLock());
    525     if (s_loadedCiphersAndCerts)
    526         return;
    527     s_loadedCiphersAndCerts = true;
    528 
    529     resetDefaultCiphers();
    530     resetDefaultEllipticCurves();
    531 
    532 #if QT_CONFIG(library)
    533     //load symbols needed to receive certificates from system store
    534 #if defined(Q_OS_WIN)
    535     HINSTANCE hLib = LoadLibraryW(L"Crypt32");
    536     if (hLib) {
    537         ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW");
    538         ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore");
    539         ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore");
    540         if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
    541             qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
    542     } else {
    543         qCWarning(lcSsl, "could not load crypt32 library"); // should never happen
    544     }
    545 #elif defined(Q_OS_QNX)
    546     s_loadRootCertsOnDemand = true;
    547 #elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
    548     // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
    549     QList<QByteArray> dirs = unixRootCertDirectories();
    550     QStringList symLinkFilter;
    551     symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
    552     for (int a = 0; a < dirs.count(); ++a) {
    553         QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
    554         if (iterator.hasNext()) {
    555             s_loadRootCertsOnDemand = true;
    556             break;
    557         }
    558     }
    559 #endif
    560 #endif // QT_CONFIG(library)
    561     // if on-demand loading was not enabled, load the certs now
    562     if (!s_loadRootCertsOnDemand)
    563         setDefaultCaCertificates(systemCaCertificates());
    564 #ifdef Q_OS_WIN
    565     //Enabled for fetching additional root certs from windows update on windows 6+
    566     //This flag is set false by setDefaultCaCertificates() indicating the app uses
    567     //its own cert bundle rather than the system one.
    568     //Same logic that disables the unix on demand cert loading.
    569     //Unlike unix, we do preload the certificates from the cert store.
    570     if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0)
    571         s_loadRootCertsOnDemand = true;
    572 #endif
    573 }
    574 
    575403/*!
    576404    \internal
    577405
    void QSslSocketPrivate::ensureInitialized() 
    587415    ensureCiphersAndCertsLoaded();
    588416}
    589417
    590 long QSslSocketPrivate::sslLibraryVersionNumber()
    591 {
    592     if (!supportsSsl())
    593         return 0;
    594 
    595     return q_SSLeay();
    596 }
    597 
    598 QString QSslSocketPrivate::sslLibraryVersionString()
    599 {
    600     if (!supportsSsl())
    601         return QString();
    602 
    603     const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
    604     if (!versionString)
    605         return QString();
    606 
    607     return QString::fromLatin1(versionString);
    608 }
    609 
    610418long QSslSocketPrivate::sslLibraryBuildVersionNumber()
    611419{
    612420    return OPENSSL_VERSION_NUMBER;
    QString QSslSocketPrivate::sslLibraryBuildVersionString() 
    628436*/
    629437void QSslSocketPrivate::resetDefaultCiphers()
    630438{
     439#if QT_CONFIG(opensslv11)
     440    SSL_CTX *myCtx = q_SSL_CTX_new(q_TLS_client_method());
     441#else
    631442    SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());
     443#endif
    632444    SSL *mySsl = q_SSL_new(myCtx);
    633445
    634446    QList<QSslCipher> ciphers;
    void QSslSocketPrivate::resetDefaultEllipticCurves() 
    664476    QVector<QSslEllipticCurve> curves;
    665477
    666478#ifndef OPENSSL_NO_EC
    667     const size_t curveCount = q_EC_get_builtin_curves(NULL, 0);
     479    const size_t curveCount = q_EC_get_builtin_curves(nullptr, 0);
    668480
    669481    QVarLengthArray<EC_builtin_curve> builtinCurves(static_cast<int>(curveCount));
    670482
    QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates() 
    698510    if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
    699511        HCERTSTORE hSystemStore;
    700512        hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT");
    701         if(hSystemStore) {
    702             PCCERT_CONTEXT pc = NULL;
    703             while(1) {
    704                 pc = ptrCertFindCertificateInStore( hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pc);
    705                 if(!pc)
     513        if (hSystemStore) {
     514            PCCERT_CONTEXT pc = nullptr;
     515            while (1) {
     516                pc = ptrCertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc);
     517                if (!pc)
    706518                    break;
    707                 QByteArray der((const char *)(pc->pbCertEncoded), static_cast<int>(pc->cbCertEncoded));
     519                QByteArray der(reinterpret_cast<const char *>(pc->pbCertEncoded),
     520                               static_cast<int>(pc->cbCertEncoded));
    708521                QSslCertificate cert(der, QSsl::Der);
    709522                systemCerts.append(cert);
    710523            }
    QSslCipher QSslSocketBackendPrivate::sessionCipher() const 
    15041317{
    15051318    if (!ssl)
    15061319        return QSslCipher();
    1507 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    1508     // FIXME This is fairly evil, but needed to keep source level compatibility
    1509     // with the OpenSSL 0.9.x implementation at maximum -- some other functions
    1510     // don't take a const SSL_CIPHER* when they should
    1511     SSL_CIPHER *sessionCipher = const_cast<SSL_CIPHER *>(q_SSL_get_current_cipher(ssl));
    1512 #else
    1513     SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
    1514 #endif
     1320
     1321    const SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
    15151322    return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher();
    15161323}
    15171324
    QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const 
    15371344    return QSsl::UnknownProtocol;
    15381345}
    15391346
    1540 void QSslSocketBackendPrivate::continueHandshake()
    1541 {
    1542     Q_Q(QSslSocket);
    1543     // if we have a max read buffer size, reset the plain socket's to match
    1544     if (readBufferMaxSize)
    1545         plainSocket->setReadBufferSize(readBufferMaxSize);
    1546 
    1547     if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL))
    1548         configuration.peerSessionShared = true;
    1549 
    1550 #ifdef QT_DECRYPT_SSL_TRAFFIC
    1551     if (ssl->session && ssl->s3) {
    1552         const char *mk = reinterpret_cast<const char *>(ssl->session->master_key);
    1553         QByteArray masterKey(mk, ssl->session->master_key_length);
    1554         const char *random = reinterpret_cast<const char *>(ssl->s3->client_random);
    1555         QByteArray clientRandom(random, SSL3_RANDOM_SIZE);
    1556 
    1557         // different format, needed for e.g. older Wireshark versions:
    1558 //        const char *sid = reinterpret_cast<const char *>(ssl->session->session_id);
    1559 //        QByteArray sessionID(sid, ssl->session->session_id_length);
    1560 //        QByteArray debugLineRSA("RSA Session-ID:");
    1561 //        debugLineRSA.append(sessionID.toHex().toUpper());
    1562 //        debugLineRSA.append(" Master-Key:");
    1563 //        debugLineRSA.append(masterKey.toHex().toUpper());
    1564 //        debugLineRSA.append("\n");
    1565 
    1566         QByteArray debugLineClientRandom("CLIENT_RANDOM ");
    1567         debugLineClientRandom.append(clientRandom.toHex().toUpper());
    1568         debugLineClientRandom.append(" ");
    1569         debugLineClientRandom.append(masterKey.toHex().toUpper());
    1570         debugLineClientRandom.append("\n");
    1571 
    1572         QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
    1573         QFile file(sslKeyFile);
    1574         if (!file.open(QIODevice::Append))
    1575             qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
    1576         if (!file.write(debugLineClientRandom))
    1577             qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
    1578         file.close();
    1579     } else {
    1580         qCWarning(lcSsl, "could not decrypt SSL traffic");
    1581     }
    1582 #endif
    1583 
    1584     // Cache this SSL session inside the QSslContext
    1585     if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
    1586         if (!sslContextPointer->cacheSession(ssl)) {
    1587             sslContextPointer.clear(); // we could not cache the session
    1588         } else {
    1589             // Cache the session for permanent usage as well
    1590             if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
    1591                 if (!sslContextPointer->sessionASN1().isEmpty())
    1592                     configuration.sslSession = sslContextPointer->sessionASN1();
    1593                 configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
    1594             }
    1595         }
    1596     }
    1597 
    1598 #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
    1599 
    1600     configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
    1601     if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
    1602         // we could not agree -> be conservative and use HTTP/1.1
    1603         configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
    1604     } else {
    1605         const unsigned char *proto = 0;
    1606         unsigned int proto_len = 0;
    1607 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
    1608         if (q_SSLeay() >= 0x10002000L) {
    1609             q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
    1610             if (proto_len && mode == QSslSocket::SslClientMode) {
    1611                 // Client does not have a callback that sets it ...
    1612                 configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
    1613             }
    1614         }
    1615 
    1616         if (!proto_len) { // Test if NPN was more lucky ...
    1617 #else
    1618         {
    1619 #endif
    1620             q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
    1621         }
    1622 
    1623         if (proto_len)
    1624             configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
    1625         else
    1626             configuration.nextNegotiatedProtocol.clear();
    1627     }
    1628 #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
    1629 
    1630 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
    1631     if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) {
    1632         EVP_PKEY *key;
    1633         if (q_SSL_get_server_tmp_key(ssl, &key))
    1634             configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
    1635     }
    1636 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
    1637 
    1638     connectionEncrypted = true;
    1639     emit q->encrypted();
    1640     if (autoStartHandshake && pendingClose) {
    1641         pendingClose = false;
    1642         q->disconnectFromHost();
    1643     }
    1644 }
    1645 
    16461347QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509)
    16471348{
    16481349    ensureInitialized();
    QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> & 
    16961397    QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
    16971398
    16981399    // Register a custom callback to get all verification errors.
    1699     X509_STORE_set_verify_cb_func(certStore, q_X509Callback);
     1400    q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
    17001401
    17011402    // Build the chain of intermediate certificates
    17021403    STACK_OF(X509) *intermediates = 0;
    17031404    if (certificateChain.length() > 1) {
    1704         intermediates = (STACK_OF(X509) *) q_sk_new_null();
     1405        intermediates = (STACK_OF(X509) *) q_OPENSSL_sk_new_null();
    17051406
    17061407        if (!intermediates) {
    17071408            q_X509_STORE_free(certStore);
    QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> & 
    17151416                first = false;
    17161417                continue;
    17171418            }
    1718 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    1719             q_sk_push( (_STACK *)intermediates, reinterpret_cast<X509 *>(cert.handle()));
    1720 #else
    1721             q_sk_push( (STACK *)intermediates, reinterpret_cast<char *>(cert.handle()));
    1722 #endif
     1419
     1420            q_OPENSSL_sk_push((OPENSSL_STACK *)intermediates, reinterpret_cast<X509 *>(cert.handle()));
    17231421        }
    17241422    }
    17251423
    QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> & 
    17431441    (void) q_X509_verify_cert(storeContext);
    17441442
    17451443    q_X509_STORE_CTX_free(storeContext);
    1746 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    1747     q_sk_free( (_STACK *) intermediates);
    1748 #else
    1749     q_sk_free( (STACK *) intermediates);
    1750 #endif
     1444    q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates);
    17511445
    17521446    // Now process the errors
    17531447    const auto errorList = std::move(_q_sslErrorList()->errors);
    bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, 
    18211515    // Convert to Qt types
    18221516    if (!key->d->fromEVP_PKEY(pkey)) {
    18231517        qCWarning(lcSsl, "Unable to convert private key");
    1824         q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free));
     1518        q_OPENSSL_sk_pop_free(reinterpret_cast<OPENSSL_STACK *>(ca),
     1519                              reinterpret_cast<void (*)(void *)>(q_OPENSSL_sk_free));
    18251520        q_X509_free(x509);
    18261521        q_EVP_PKEY_free(pkey);
    18271522        q_PKCS12_free(p12);
    bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, 
    18361531        *caCertificates = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ca);
    18371532
    18381533    // Clean up
    1839     q_sk_pop_free(reinterpret_cast<STACK *>(ca), reinterpret_cast<void(*)(void*)>(q_sk_free));
     1534    // TODO: verify ASAP, in the past we had sk_pop_free with q_OPENSSL_sk_free
     1535    // which seems to be blatantly wrong and even crashes with 1.1.
     1536    q_OPENSSL_sk_pop_free(reinterpret_cast<OPENSSL_STACK *>(ca),
     1537                          reinterpret_cast<void (*)(void *)>(q_X509_free));
     1538
    18401539    q_X509_free(x509);
    18411540    q_EVP_PKEY_free(pkey);
    18421541    q_PKCS12_free(p12);
  • new file qtbase/src/network/ssl/qsslsocket_openssl11.cpp

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl11.cpp b/qtbase/src/network/ssl/qsslsocket_openssl11.cpp
    new file mode 100644
    index 0000000000000000000000000000000000000000..b6d18943a5ab6e2d3af68dd767a9c58a7edc6c8e
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 Governikus GmbH & Co. KG
     5** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
     6** Contact: https://www.qt.io/licensing/
     7**
     8** This file is part of the QtNetwork module of the Qt Toolkit.
     9**
     10** $QT_BEGIN_LICENSE:LGPL$
     11** Commercial License Usage
     12** Licensees holding valid commercial Qt licenses may use this file in
     13** accordance with the commercial license agreement provided with the
     14** Software or, alternatively, in accordance with the terms contained in
     15** a written agreement between you and The Qt Company. For licensing terms
     16** and conditions see https://www.qt.io/terms-conditions. For further
     17** information use the contact form at https://www.qt.io/contact-us.
     18**
     19** GNU Lesser General Public License Usage
     20** Alternatively, this file may be used under the terms of the GNU Lesser
     21** General Public License version 3 as published by the Free Software
     22** Foundation and appearing in the file LICENSE.LGPL3 included in the
     23** packaging of this file. Please review the following information to
     24** ensure the GNU Lesser General Public License version 3 requirements
     25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     26**
     27** GNU General Public License Usage
     28** Alternatively, this file may be used under the terms of the GNU
     29** General Public License version 2.0 or (at your option) the GNU General
     30** Public license version 3 or any later version approved by the KDE Free
     31** Qt Foundation. The licenses are as published by the Free Software
     32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     33** included in the packaging of this file. Please review the following
     34** information to ensure the GNU General Public License requirements will
     35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     36** https://www.gnu.org/licenses/gpl-3.0.html.
     37**
     38** $QT_END_LICENSE$
     39**
     40****************************************************************************/
     41
     42/****************************************************************************
     43**
     44** In addition, as a special exception, the copyright holders listed above give
     45** permission to link the code of its release of Qt with the OpenSSL project's
     46** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
     47** same license as the original version), and distribute the linked executables.
     48**
     49** You must comply with the GNU General Public License version 2 in all
     50** respects for all of the code used other than the "OpenSSL" code.  If you
     51** modify this file, you may extend this exception to your version of the file,
     52** but you are not obligated to do so.  If you do not wish to do so, delete
     53** this exception statement from your version of this file.
     54**
     55****************************************************************************/
     56
     57//#define QT_DECRYPT_SSL_TRAFFIC
     58
     59#include "qssl_p.h"
     60#include "qsslsocket_openssl_p.h"
     61#include "qsslsocket_openssl_symbols_p.h"
     62#include "qsslsocket.h"
     63#include "qsslkey.h"
     64
     65#include <QtCore/qdebug.h>
     66#include <QtCore/qdir.h>
     67#include <QtCore/qdiriterator.h>
     68#include <QtCore/qfile.h>
     69#include <QtCore/qmutex.h>
     70#include <QtCore/qlibrary.h>
     71
     72QT_BEGIN_NAMESPACE
     73
     74Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_opensslInitMutex, (QMutex::Recursive))
     75
     76/*!
     77    \internal
     78*/
     79void QSslSocketPrivate::deinitialize()
     80{
     81    // This function exists only for compatibility with the pre-11 code,
     82    // where deinitialize() actually does some cleanup. To be discarded
     83    // once we retire < 1.1.
     84}
     85
     86bool QSslSocketPrivate::ensureLibraryLoaded()
     87{
     88    if (!q_resolveOpenSslSymbols())
     89        return false;
     90
     91    const QMutexLocker locker(qt_opensslInitMutex);
     92
     93    if (!s_libraryLoaded) {
     94        s_libraryLoaded = true;
     95
     96        // Initialize OpenSSL.
     97        if (q_OPENSSL_init_ssl(0, nullptr) != 1)
     98            return false;
     99        q_SSL_load_error_strings();
     100        q_OpenSSL_add_all_algorithms();
     101
     102        QSslSocketBackendPrivate::s_indexForSSLExtraData
     103            = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr,
     104                                        nullptr, nullptr);
     105
     106        // Initialize OpenSSL's random seed.
     107        if (!q_RAND_status()) {
     108            qWarning("Random number generator not seeded, disabling SSL support");
     109            return false;
     110        }
     111    }
     112    return true;
     113}
     114
     115void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
     116{
     117    const QMutexLocker locker(qt_opensslInitMutex);
     118
     119    if (s_loadedCiphersAndCerts)
     120        return;
     121    s_loadedCiphersAndCerts = true;
     122
     123    resetDefaultCiphers();
     124    resetDefaultEllipticCurves();
     125
     126#if QT_CONFIG(library)
     127    //load symbols needed to receive certificates from system store
     128#if defined(Q_OS_WIN)
     129    HINSTANCE hLib = LoadLibraryW(L"Crypt32");
     130    if (hLib) {
     131        ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW");
     132        ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore");
     133        ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore");
     134        if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
     135            qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
     136    } else {
     137        qCWarning(lcSsl, "could not load crypt32 library"); // should never happen
     138    }
     139#elif defined(Q_OS_QNX)
     140    s_loadRootCertsOnDemand = true;
     141#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
     142    // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
     143    QList<QByteArray> dirs = unixRootCertDirectories();
     144    QStringList symLinkFilter;
     145    symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
     146    for (int a = 0; a < dirs.count(); ++a) {
     147        QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
     148        if (iterator.hasNext()) {
     149            s_loadRootCertsOnDemand = true;
     150            break;
     151        }
     152    }
     153#endif
     154#endif // QT_CONFIG(library)
     155    // if on-demand loading was not enabled, load the certs now
     156    if (!s_loadRootCertsOnDemand)
     157        setDefaultCaCertificates(systemCaCertificates());
     158#ifdef Q_OS_WIN
     159    //Enabled for fetching additional root certs from windows update on windows 6+
     160    //This flag is set false by setDefaultCaCertificates() indicating the app uses
     161    //its own cert bundle rather than the system one.
     162    //Same logic that disables the unix on demand cert loading.
     163    //Unlike unix, we do preload the certificates from the cert store.
     164    if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0)
     165        s_loadRootCertsOnDemand = true;
     166#endif
     167}
     168
     169long QSslSocketPrivate::sslLibraryVersionNumber()
     170{
     171    if (!supportsSsl())
     172        return 0;
     173
     174    return q_OpenSSL_version_num();
     175}
     176
     177QString QSslSocketPrivate::sslLibraryVersionString()
     178{
     179    if (!supportsSsl())
     180        return QString();
     181
     182    const char *versionString = q_OpenSSL_version(OPENSSL_VERSION);
     183    if (!versionString)
     184        return QString();
     185
     186    return QString::fromLatin1(versionString);
     187}
     188
     189void QSslSocketBackendPrivate::continueHandshake()
     190{
     191    Q_Q(QSslSocket);
     192    // if we have a max read buffer size, reset the plain socket's to match
     193    if (readBufferMaxSize)
     194        plainSocket->setReadBufferSize(readBufferMaxSize);
     195
     196    if (q_SSL_session_reused(ssl))
     197        configuration.peerSessionShared = true;
     198
     199#ifdef QT_DECRYPT_SSL_TRAFFIC
     200    if (q_SSL_get_session(ssl)) {
     201        size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), 0, 0);
     202        size_t client_random_len = q_SSL_get_client_random(ssl, 0, 0);
     203        QByteArray masterKey(int(master_key_len), 0); // Will not overflow
     204        QByteArray clientRandom(int(client_random_len), 0); // Will not overflow
     205
     206        q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl),
     207                                     reinterpret_cast<unsigned char*>(masterKey.data()),
     208                                     masterKey.size());
     209        q_SSL_get_client_random(ssl, reinterpret_cast<unsigned char *>(clientRandom.data()),
     210                                clientRandom.size());
     211
     212        QByteArray debugLineClientRandom("CLIENT_RANDOM ");
     213        debugLineClientRandom.append(clientRandom.toHex().toUpper());
     214        debugLineClientRandom.append(" ");
     215        debugLineClientRandom.append(masterKey.toHex().toUpper());
     216        debugLineClientRandom.append("\n");
     217
     218        QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
     219        QFile file(sslKeyFile);
     220        if (!file.open(QIODevice::Append))
     221            qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
     222        if (!file.write(debugLineClientRandom))
     223            qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
     224        file.close();
     225    } else {
     226        qCWarning(lcSsl, "could not decrypt SSL traffic");
     227    }
     228#endif
     229
     230    // Cache this SSL session inside the QSslContext
     231    if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
     232        if (!sslContextPointer->cacheSession(ssl)) {
     233            sslContextPointer.clear(); // we could not cache the session
     234        } else {
     235            // Cache the session for permanent usage as well
     236            if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
     237                if (!sslContextPointer->sessionASN1().isEmpty())
     238                    configuration.sslSession = sslContextPointer->sessionASN1();
     239                configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
     240            }
     241        }
     242    }
     243
     244#if !defined(OPENSSL_NO_NEXTPROTONEG)
     245
     246    configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
     247    if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
     248        // we could not agree -> be conservative and use HTTP/1.1
     249        configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
     250    } else {
     251        const unsigned char *proto = 0;
     252        unsigned int proto_len = 0;
     253
     254        q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
     255        if (proto_len && mode == QSslSocket::SslClientMode) {
     256            // Client does not have a callback that sets it ...
     257            configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
     258        }
     259
     260        if (!proto_len) { // Test if NPN was more lucky ...
     261            q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
     262        }
     263
     264        if (proto_len)
     265            configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
     266        else
     267            configuration.nextNegotiatedProtocol.clear();
     268    }
     269#endif // !defined(OPENSSL_NO_NEXTPROTONEG)
     270
     271    if (mode == QSslSocket::SslClientMode) {
     272        EVP_PKEY *key;
     273        if (q_SSL_get_server_tmp_key(ssl, &key))
     274            configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
     275    }
     276
     277    connectionEncrypted = true;
     278    emit q->encrypted();
     279    if (autoStartHandshake && pendingClose) {
     280        pendingClose = false;
     281        q->disconnectFromHost();
     282    }
     283}
     284
     285QT_END_NAMESPACE
  • new file qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h
    new file mode 100644
    index 0000000000000000000000000000000000000000..2980b3d23ed3022c1b7f34eb0ad0a009d6084b31
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
     5** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
     6** Contact: https://www.qt.io/licensing/
     7**
     8** This file is part of the QtNetwork module of the Qt Toolkit.
     9**
     10** $QT_BEGIN_LICENSE:LGPL$
     11** Commercial License Usage
     12** Licensees holding valid commercial Qt licenses may use this file in
     13** accordance with the commercial license agreement provided with the
     14** Software or, alternatively, in accordance with the terms contained in
     15** a written agreement between you and The Qt Company. For licensing terms
     16** and conditions see https://www.qt.io/terms-conditions. For further
     17** information use the contact form at https://www.qt.io/contact-us.
     18**
     19** GNU Lesser General Public License Usage
     20** Alternatively, this file may be used under the terms of the GNU Lesser
     21** General Public License version 3 as published by the Free Software
     22** Foundation and appearing in the file LICENSE.LGPL3 included in the
     23** packaging of this file. Please review the following information to
     24** ensure the GNU Lesser General Public License version 3 requirements
     25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     26**
     27** GNU General Public License Usage
     28** Alternatively, this file may be used under the terms of the GNU
     29** General Public License version 2.0 or (at your option) the GNU General
     30** Public license version 3 or any later version approved by the KDE Free
     31** Qt Foundation. The licenses are as published by the Free Software
     32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     33** included in the packaging of this file. Please review the following
     34** information to ensure the GNU General Public License requirements will
     35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     36** https://www.gnu.org/licenses/gpl-3.0.html.
     37**
     38** $QT_END_LICENSE$
     39**
     40****************************************************************************/
     41
     42/****************************************************************************
     43**
     44** In addition, as a special exception, the copyright holders listed above give
     45** permission to link the code of its release of Qt with the OpenSSL project's
     46** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
     47** same license as the original version), and distribute the linked executables.
     48**
     49** You must comply with the GNU General Public License version 2 in all
     50** respects for all of the code used other than the "OpenSSL" code.  If you
     51** modify this file, you may extend this exception to your version of the file,
     52** but you are not obligated to do so.  If you do not wish to do so, delete
     53** this exception statement from your version of this file.
     54**
     55****************************************************************************/
     56
     57#ifndef QSSLSOCKET_OPENSSL11_SYMBOLS_P_H
     58#define QSSLSOCKET_OPENSSL11_SYMBOLS_P_H
     59
     60//
     61//  W A R N I N G
     62//  -------------
     63//
     64// This file is not part of the Qt API. It exists purely as an
     65// implementation detail. This header file may change from version to
     66// version without notice, or even be removed.
     67//
     68// We mean it.
     69//
     70
     71// Note: this file does not have QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, it's done
     72// in qsslsocket_openssl_symbols_p.h.
     73
     74#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H
     75#error "You are not supposed to use this header file, include qsslsocket_openssl_symbols_p.h instead"
     76#endif
     77
     78const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x);
     79
     80Q_AUTOTEST_EXPORT BIO *q_BIO_new(const BIO_METHOD *a);
     81Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
     82
     83int q_DSA_bits(DSA *a);
     84int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
     85int q_EVP_PKEY_base_id(EVP_PKEY *a);
     86int q_RSA_bits(RSA *a);
     87int q_OPENSSL_sk_num(OPENSSL_STACK *a);
     88void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
     89OPENSSL_STACK *q_OPENSSL_sk_new_null();
     90void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
     91void q_OPENSSL_sk_free(OPENSSL_STACK *a);
     92void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
     93int q_SSL_session_reused(SSL *a);
     94unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
     95int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
     96size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen);
     97size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen);
     98int q_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
     99const SSL_METHOD *q_TLS_method();
     100const SSL_METHOD *q_TLS_client_method();
     101const SSL_METHOD *q_TLS_server_method();
     102ASN1_TIME *q_X509_getm_notBefore(X509 *a);
     103ASN1_TIME *q_X509_getm_notAfter(X509 *a);
     104
     105long q_X509_get_version(X509 *a);
     106EVP_PKEY *q_X509_get_pubkey(X509 *a);
     107void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
     108STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
     109void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
     110int q_DH_bits(DH *dh);
     111
     112# define q_SSL_load_error_strings() q_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
     113                                                       | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
     114
     115#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_OPENSSL_sk_num)(st)
     116#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_OPENSSL_sk_value)(st, i)
     117
     118#define q_OPENSSL_add_all_algorithms_conf()  q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
     119                                                                   | OPENSSL_INIT_ADD_ALL_DIGESTS \
     120                                                                   | OPENSSL_INIT_LOAD_CONFIG, NULL)
     121#define  q_OPENSSL_add_all_algorithms_noconf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
     122                                                                    | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
     123
     124int q_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
     125void q_CRYPTO_free(void *str, const char *file, int line);
     126
     127long q_OpenSSL_version_num();
     128const char *q_OpenSSL_version(int type);
     129
     130unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session);
     131
     132#endif
  • qtbase/src/network/ssl/qsslsocket_openssl_p.h

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h
    index b2adb3e5473f2c4ddc6967f960a52547d20f762b..7f9e884045866f1bc0887053b5124d26144b5c31 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
    44** Contact: https://www.qt.io/licensing/
    55**
    66** This file is part of the QtNetwork module of the Qt Toolkit.
     
    9898#include <openssl/crypto.h>
    9999#include <openssl/tls1.h>
    100100
    101 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    102 typedef _STACK STACK;
     101#if QT_CONFIG(opensslv11)
     102#include <openssl/dh.h>
    103103#endif
    104104
    105105QT_BEGIN_NAMESPACE
    public: 
    151151#endif
    152152
    153153    Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions);
    154     static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher);
     154    static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher);
    155155    static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
    156156    static QList<QSslError> verify(const QList<QSslCertificate> &certificateChain, const QString &hostName);
    157157    static QString getErrorsFromOpenSsl();
  • qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp
    index ce02e0bc017dc1137e3493b0ca5715d31a600006..5f0d82e2c38af7b71122eae37b928963aab69003 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
    44** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
     5** Copyright (C) 2016 Richard J. Moore <rich@kde.org>
    56** Contact: https://www.qt.io/licensing/
    67**
    78** This file is part of the QtNetwork module of the Qt Toolkit.
    void qsslSocketCannotResolveSymbolWarning(const char *functionName) 
    136137
    137138#endif // QT_LINKED_OPENSSL
    138139
     140#if QT_CONFIG(opensslv11)
     141
     142// Below are the functions first introduced in version 1.1:
     143
     144DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return 0, return)
     145DEFINEFUNC2(int, OPENSSL_init_ssl, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
     146DEFINEFUNC2(int, OPENSSL_init_crypto, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return)
     147DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return 0, return)
     148DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
     149DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
     150DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return)
     151DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
     152DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
     153DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
     154DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
     155DEFINEFUNC2(void, OPENSSL_sk_pop_free, OPENSSL_STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
     156DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
     157DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMMYARG)
     158DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG)
     159DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return 0, return)
     160DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return)
     161DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return)
     162DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return)
     163DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return)
     164DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
     165
     166DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return 0, return)
     167DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return 0, return)
     168DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return 0, return)
     169DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return 0, return)
     170DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return 0, return)
     171DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
     172DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return 0, return)
     173DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
     174DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return 0, return)
     175DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
     176DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
     177DEFINEFUNC(const char *, OpenSSL_version, int a, a, return 0, return)
     178DEFINEFUNC(unsigned long, SSL_SESSION_get_ticket_lifetime_hint, const SSL_SESSION *session, session, return 0, return)
     179DEFINEFUNC4(void, DH_get0_pqg, const DH *dh, dh, const BIGNUM **p, p, const BIGNUM **q, q, const BIGNUM **g, g, return, DUMMYARG)
     180DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return)
     181
     182#else // QT_CONFIG(opensslv11)
     183
     184// Functions below are either deprecated or removed in OpenSSL >= 1.1:
     185
     186DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
     187
    139188#ifdef SSLEAY_MACROS
    140189DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return)
    141190#endif
     191DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return 0, return)
     192DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG)
     193DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
     194DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
     195DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
     196DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
     197DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
     198DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
     199DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
     200DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
     201DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
     202DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
     203
     204#ifdef SSLEAY_MACROS
     205DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
     206DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
     207#endif // SSLEAY_MACROS
     208
     209DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
     210DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
     211
     212#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     213DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
     214DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
     215DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
     216DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
     217#else
     218DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
     219DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG)
     220DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
     221DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
     222#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
     223
     224DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
     225DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
     226
     227#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     228DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
     229#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L
     230
     231#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     232#ifndef OPENSSL_NO_SSL2
     233DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
     234#endif
     235#ifndef OPENSSL_NO_SSL3_METHOD
     236DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
     237#endif
     238DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
     239DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
     240#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     241DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
     242DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
     243#endif
     244#ifndef OPENSSL_NO_SSL2
     245DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
     246#endif
     247#ifndef OPENSSL_NO_SSL3_METHOD
     248DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
     249#endif
     250DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
     251DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
     252#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     253DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
     254DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
     255#endif
     256#else
     257#ifndef OPENSSL_NO_SSL2
     258DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
     259#endif
     260#ifndef OPENSSL_NO_SSL3_METHOD
     261DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
     262#endif
     263DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
     264DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
     265#ifndef OPENSSL_NO_SSL2
     266DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
     267#endif
     268#ifndef OPENSSL_NO_SSL3_METHOD
     269DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
     270#endif
     271DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
     272DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
     273#endif
     274
     275DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return)
     276
     277#ifdef SSLEAY_MACROS
     278DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
     279DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
     280#ifndef OPENSSL_NO_EC
     281DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return)
     282#endif
     283DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
     284DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
     285#ifndef OPENSSL_NO_EC
     286DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return)
     287#endif
     288#endif
     289DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return 0, return)
     290DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
     291DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
     292DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
     293DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
     294
     295#endif // QT_CONFIG(opensslv11)
     296
    142297DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return)
    143 DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return)
    144298DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return)
    145 DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return);
     299DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return)
    146300DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return)
    147301DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return)
    148 DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return)
    149302DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return)
    150303DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return)
    151 DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return)
     304
    152305DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return)
    153306DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return)
    154 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
    155 DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
    156 #endif
    157307DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return static_cast<BN_ULONG>(-1), return)
    158308#ifndef OPENSSL_NO_EC
    159309DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return)
    160310DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return)
    161311#endif
    162 DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
    163 DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
    164 DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
    165 DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
    166312DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return)
    167313DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG)
    168314DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return)
    169315DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return)
    170316DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return)
    171 DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
    172 DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
    173 DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
    174 DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return);
     317DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return 0, return)
     318DEFINEFUNC(void, EVP_CIPHER_CTX_free, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
     319DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return)
    175320DEFINEFUNC2(int, EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX *ctx, ctx, int keylen, keylen, return 0, return)
    176 DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *type, type, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return);
    177 DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return);
    178 DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return);
     321DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *type, type, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return)
     322DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *cipher, cipher, ENGINE *impl, impl, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return)
     323DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return)
     324DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return)
    179325DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return 0, return)
    180326DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return)
    181327DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return 0, return)
     328DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return 0, return)
    182329DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return)
    183330DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return)
    184331DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return)
    DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, retur 
    202349DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return)
    203350
    204351DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
    205 #ifdef SSLEAY_MACROS
    206 DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
    207 DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
    208 #else
     352
     353#ifndef SSLEAY_MACROS
    209354DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    210355DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    211356DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CI 
    218363#ifndef OPENSSL_NO_EC
    219364DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return)
    220365#endif
    221 #endif
     366#endif // !SSLEAY_MACROS
    222367DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    223368DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    224369DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return)
    DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG) 
    234379DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return)
    235380DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return)
    236381DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG)
    237 DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return)
    238 DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG)
    239 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    240 DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
    241 DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG)
    242 DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG)
    243 DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return)
    244 #else
    245 DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return)
    246 DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG)
    247 DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG)
    248 DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return)
    249 #endif
    250382DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return)
    251383DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return)
    252 DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
    253 DEFINEFUNC2(int, SSL_CIPHER_get_bits, SSL_CIPHER *a, a, int *b, b, return 0, return)
     384DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return)
     385DEFINEFUNC2(int, SSL_CIPHER_get_bits, const SSL_CIPHER *a, a, int *b, b, return 0, return)
    254386DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return)
    255387DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return)
    256388DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return)
    DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return) 
    287419#else
    288420DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return)
    289421#endif
    290 DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return)
    291 DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG)
    292422DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return)
    293423DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return)
    294424DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return)
    DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG) 
    301431DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return 0, return)
    302432DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return)
    303433#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    304 DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return)
    305434DEFINEFUNC3(int, SSL_set_ex_data, SSL *ssl, ssl, int idx, idx, void *arg, arg, return 0, return)
    306435DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return NULL, return)
    307436#endif
    DEFINEFUNC2(void, SSL_set_psk_client_callback, SSL* ssl, ssl, q_psk_client_callb 
    310439DEFINEFUNC2(void, SSL_set_psk_server_callback, SSL* ssl, ssl, q_psk_server_callback_t callback, callback, return, DUMMYARG)
    311440DEFINEFUNC2(int, SSL_CTX_use_psk_identity_hint, SSL_CTX* ctx, ctx, const char *hint, hint, return 0, return)
    312441#endif
    313 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    314 #ifndef OPENSSL_NO_SSL2
    315 DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
    316 #endif
    317 #ifndef OPENSSL_NO_SSL3_METHOD
    318 DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
    319 #endif
    320 DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
    321 DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
    322 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    323 DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
    324 DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
    325 #endif
    326 #ifndef OPENSSL_NO_SSL2
    327 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
    328 #endif
    329 #ifndef OPENSSL_NO_SSL3_METHOD
    330 DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
    331 #endif
    332 DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
    333 DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
    334 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    335 DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
    336 DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
    337 #endif
    338 #else
    339 #ifndef OPENSSL_NO_SSL2
    340 DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
    341 #endif
    342 #ifndef OPENSSL_NO_SSL3_METHOD
    343 DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
    344 #endif
    345 DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
    346 DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
    347 #ifndef OPENSSL_NO_SSL2
    348 DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
    349 #endif
    350 #ifndef OPENSSL_NO_SSL3_METHOD
    351 DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
    352 #endif
    353 DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
    354 DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
    355 #endif
    356442DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return)
    357443DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return)
     444DEFINEFUNC4(int, X509_digest, const X509 *x509, x509, const EVP_MD *type, type, unsigned char *md, md, unsigned int *len, len, return -1, return)
    358445#ifndef SSLEAY_MACROS
    359446DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return)
    360447#endif
    DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, retu 
    378465DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return)
    379466DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return)
    380467DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return)
     468DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return 0, return)
    381469DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return)
    382470DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return)
    383471DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return)
    DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, ret 
    393481DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
    394482DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
    395483DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return 0, return)
    396 DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return)
    397484DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return)
    398 #ifdef SSLEAY_MACROS
    399 DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return)
    400 DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return)
    401 #ifndef OPENSSL_NO_EC
    402 DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return)
    403 #endif
    404 DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return)
    405 DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return)
    406 #ifndef OPENSSL_NO_EC
    407 DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return)
    408 #endif
    409 #endif
    410 DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG)
    411 DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
    412485DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
    413 DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
    414 DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
    415486DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
    416487DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
    417488#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
    static QPair<QLibrary*, QLibrary*> loadOpenSsl() 
    695766#ifndef Q_OS_DARWIN
    696767    // second attempt: find the development files libssl.so and libcrypto.so
    697768    //
    698     // disabled on OS X/iOS:
    699     //  OS X's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
     769    // disabled on macOS/iOS:
     770    //  macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
    700771    //    attempt, _after_ <bundle>/Contents/Frameworks has been searched.
    701772    //  iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
    702773    libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
    bool q_resolveOpenSslSymbols() 
    755826    static bool symbolsResolved = false;
    756827    static bool triedToResolveSymbols = false;
    757828#ifndef QT_NO_THREAD
     829#if QT_CONFIG(opensslv11)
     830    QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl));
     831#else
    758832    QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init));
     833#endif
    759834#endif
    760835    if (symbolsResolved)
    761836        return true;
    bool q_resolveOpenSslSymbols() 
    772847        // failed to load them
    773848        return false;
    774849
     850#if QT_CONFIG(opensslv11)
     851
     852    RESOLVEFUNC(OPENSSL_init_ssl)
     853    RESOLVEFUNC(OPENSSL_init_crypto)
     854    RESOLVEFUNC(ASN1_STRING_get0_data)
     855    RESOLVEFUNC(EVP_CIPHER_CTX_reset)
     856    RESOLVEFUNC(EVP_PKEY_base_id)
     857    RESOLVEFUNC(RSA_bits)
     858    RESOLVEFUNC(OPENSSL_sk_new_null)
     859    RESOLVEFUNC(OPENSSL_sk_push)
     860    RESOLVEFUNC(OPENSSL_sk_free)
     861    RESOLVEFUNC(OPENSSL_sk_num)
     862    RESOLVEFUNC(OPENSSL_sk_pop_free)
     863    RESOLVEFUNC(OPENSSL_sk_value)
     864    RESOLVEFUNC(DH_get0_pqg)
     865    RESOLVEFUNC(SSL_CTX_set_options)
     866    RESOLVEFUNC(SSL_get_client_random)
     867    RESOLVEFUNC(SSL_SESSION_get_master_key)
     868    RESOLVEFUNC(SSL_session_reused)
     869    RESOLVEFUNC(SSL_get_session)
     870    RESOLVEFUNC(CRYPTO_get_ex_new_index)
     871    RESOLVEFUNC(TLS_method)
     872    RESOLVEFUNC(TLS_client_method)
     873    RESOLVEFUNC(TLS_server_method)
     874    RESOLVEFUNC(X509_STORE_CTX_get0_chain)
     875    RESOLVEFUNC(X509_getm_notBefore)
     876    RESOLVEFUNC(X509_getm_notAfter)
     877    RESOLVEFUNC(X509_get_version)
     878    RESOLVEFUNC(X509_get_pubkey)
     879    RESOLVEFUNC(X509_STORE_set_verify_cb)
     880    RESOLVEFUNC(CRYPTO_free)
     881    RESOLVEFUNC(OpenSSL_version_num)
     882    RESOLVEFUNC(OpenSSL_version)
     883    if (!_q_OpenSSL_version) {
     884        // Apparently, we were built with OpenSSL 1.1 enabled but are now using
     885        // a wrong library.
     886        delete libs.first;
     887        delete libs.second;
     888        qCWarning(lcSsl, "Incompatible version of OpenSSL");
     889        return false;
     890    }
     891
     892    RESOLVEFUNC(SSL_SESSION_get_ticket_lifetime_hint)
     893    RESOLVEFUNC(DH_bits)
     894    RESOLVEFUNC(DSA_bits)
     895
     896#else // !opensslv11
     897
     898    RESOLVEFUNC(ASN1_STRING_data)
     899
    775900#ifdef SSLEAY_MACROS
    776901    RESOLVEFUNC(ASN1_dup)
     902#endif // SSLEAY_MACROS
     903    RESOLVEFUNC(BIO_new_file)
     904    RESOLVEFUNC(ERR_clear_error)
     905    RESOLVEFUNC(CRYPTO_free)
     906    RESOLVEFUNC(CRYPTO_num_locks)
     907    RESOLVEFUNC(CRYPTO_set_id_callback)
     908    RESOLVEFUNC(CRYPTO_set_locking_callback)
     909    RESOLVEFUNC(ERR_peek_last_error)
     910    RESOLVEFUNC(ERR_free_strings)
     911    RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
     912    RESOLVEFUNC(EVP_CIPHER_CTX_init)
     913
     914#ifdef SSLEAY_MACROS // ### verify
     915    RESOLVEFUNC(PEM_ASN1_read_bio)
     916#endif // SSLEAY_MACROS
     917
     918    RESOLVEFUNC(sk_new_null)
     919    RESOLVEFUNC(sk_push)
     920    RESOLVEFUNC(sk_free)
     921    RESOLVEFUNC(sk_num)
     922    RESOLVEFUNC(sk_pop_free)
     923    RESOLVEFUNC(sk_value)
     924    RESOLVEFUNC(SSL_library_init)
     925    RESOLVEFUNC(SSL_load_error_strings)
     926#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     927    RESOLVEFUNC(SSL_get_ex_new_index)
     928#endif
     929#ifndef OPENSSL_NO_SSL2
     930    RESOLVEFUNC(SSLv2_client_method)
    777931#endif
     932#ifndef OPENSSL_NO_SSL3_METHOD
     933    RESOLVEFUNC(SSLv3_client_method)
     934#endif
     935    RESOLVEFUNC(SSLv23_client_method)
     936    RESOLVEFUNC(TLSv1_client_method)
     937#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     938    RESOLVEFUNC(TLSv1_1_client_method)
     939    RESOLVEFUNC(TLSv1_2_client_method)
     940#endif
     941#ifndef OPENSSL_NO_SSL2
     942    RESOLVEFUNC(SSLv2_server_method)
     943#endif
     944#ifndef OPENSSL_NO_SSL3_METHOD
     945    RESOLVEFUNC(SSLv3_server_method)
     946#endif
     947    RESOLVEFUNC(SSLv23_server_method)
     948    RESOLVEFUNC(TLSv1_server_method)
     949#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     950    RESOLVEFUNC(TLSv1_1_server_method)
     951    RESOLVEFUNC(TLSv1_2_server_method)
     952#endif
     953    RESOLVEFUNC(X509_STORE_CTX_get_chain)
     954#ifdef SSLEAY_MACROS
     955    RESOLVEFUNC(i2d_DSAPrivateKey)
     956    RESOLVEFUNC(i2d_RSAPrivateKey)
     957    RESOLVEFUNC(d2i_DSAPrivateKey)
     958    RESOLVEFUNC(d2i_RSAPrivateKey)
     959#endif
     960    RESOLVEFUNC(CONF_get1_default_config_file)
     961    RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
     962    RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
     963    RESOLVEFUNC(SSLeay)
     964
     965    if (!_q_SSLeay || q_SSLeay() >= 0x10100000L) {
     966        // OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to
     967        // resolve this symbol as a failure to resolve symbols.
     968        // The right operand of '||' above is ... a bit of paranoia.
     969        delete libs.first;
     970        delete libs.second;
     971        qCWarning(lcSsl, "Incompatible version of OpenSSL");
     972        return false;
     973    }
     974
     975
     976    RESOLVEFUNC(SSLeay_version)
     977
     978#ifndef OPENSSL_NO_EC
     979#if OPENSSL_VERSION_NUMBER >= 0x10002000L
     980    if (q_SSLeay() >= 0x10002000L)
     981        RESOLVEFUNC(EC_curve_nist2nid)
     982#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
     983#endif // OPENSSL_NO_EC
     984
     985
     986#endif // !opensslv11
     987
    778988    RESOLVEFUNC(ASN1_INTEGER_get)
    779     RESOLVEFUNC(ASN1_STRING_data)
    780989    RESOLVEFUNC(ASN1_STRING_length)
    781990    RESOLVEFUNC(ASN1_STRING_to_UTF8)
    782991    RESOLVEFUNC(BIO_ctrl)
    bool q_resolveOpenSslSymbols() 
    7951004    RESOLVEFUNC(BN_is_word)
    7961005#endif
    7971006    RESOLVEFUNC(BN_mod_word)
    798     RESOLVEFUNC(CRYPTO_free)
    799     RESOLVEFUNC(CRYPTO_num_locks)
    800     RESOLVEFUNC(CRYPTO_set_id_callback)
    801     RESOLVEFUNC(CRYPTO_set_locking_callback)
    8021007    RESOLVEFUNC(DSA_new)
    8031008    RESOLVEFUNC(DSA_free)
    8041009    RESOLVEFUNC(ERR_error_string)
    8051010    RESOLVEFUNC(ERR_get_error)
    806     RESOLVEFUNC(ERR_free_strings)
    807     RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
    808     RESOLVEFUNC(EVP_CIPHER_CTX_init)
     1011    RESOLVEFUNC(EVP_CIPHER_CTX_new)
     1012    RESOLVEFUNC(EVP_CIPHER_CTX_free)
    8091013    RESOLVEFUNC(EVP_CIPHER_CTX_ctrl)
    8101014    RESOLVEFUNC(EVP_CIPHER_CTX_set_key_length)
    8111015    RESOLVEFUNC(EVP_CipherInit)
     1016    RESOLVEFUNC(EVP_CipherInit_ex)
    8121017    RESOLVEFUNC(EVP_CipherUpdate)
    8131018    RESOLVEFUNC(EVP_CipherFinal)
    8141019    RESOLVEFUNC(EVP_des_cbc)
    8151020    RESOLVEFUNC(EVP_des_ede3_cbc)
    8161021    RESOLVEFUNC(EVP_rc2_cbc)
     1022    RESOLVEFUNC(EVP_sha1)
    8171023    RESOLVEFUNC(EVP_PKEY_assign)
    8181024    RESOLVEFUNC(EVP_PKEY_set1_RSA)
    8191025    RESOLVEFUNC(EVP_PKEY_set1_DSA)
    bool q_resolveOpenSslSymbols() 
    8351041    RESOLVEFUNC(i2t_ASN1_OBJECT)
    8361042    RESOLVEFUNC(OBJ_obj2txt)
    8371043    RESOLVEFUNC(OBJ_obj2nid)
    838 #ifdef SSLEAY_MACROS // ### verify
    839     RESOLVEFUNC(PEM_ASN1_read_bio)
    840 #else
     1044
     1045#ifndef SSLEAY_MACROS
    8411046    RESOLVEFUNC(PEM_read_bio_PrivateKey)
    8421047    RESOLVEFUNC(PEM_read_bio_DSAPrivateKey)
    8431048    RESOLVEFUNC(PEM_read_bio_RSAPrivateKey)
    bool q_resolveOpenSslSymbols() 
    8501055#ifndef OPENSSL_NO_EC
    8511056    RESOLVEFUNC(PEM_write_bio_ECPrivateKey)
    8521057#endif
    853 #endif
     1058#endif // !SSLEAY_MACROS
     1059
    8541060    RESOLVEFUNC(PEM_read_bio_PUBKEY)
    8551061    RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY)
    8561062    RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY)
    bool q_resolveOpenSslSymbols() 
    8661072    RESOLVEFUNC(RAND_status)
    8671073    RESOLVEFUNC(RSA_new)
    8681074    RESOLVEFUNC(RSA_free)
    869     RESOLVEFUNC(sk_new_null)
    870     RESOLVEFUNC(sk_push)
    871     RESOLVEFUNC(sk_free)
    872     RESOLVEFUNC(sk_num)
    873     RESOLVEFUNC(sk_pop_free)
    874     RESOLVEFUNC(sk_value)
    8751075    RESOLVEFUNC(SSL_CIPHER_description)
    8761076    RESOLVEFUNC(SSL_CIPHER_get_bits)
    8771077    RESOLVEFUNC(SSL_CTX_check_private_key)
    bool q_resolveOpenSslSymbols() 
    8991099    RESOLVEFUNC(SSL_get_peer_cert_chain)
    9001100    RESOLVEFUNC(SSL_get_peer_certificate)
    9011101    RESOLVEFUNC(SSL_get_verify_result)
    902     RESOLVEFUNC(SSL_library_init)
    903     RESOLVEFUNC(SSL_load_error_strings)
    9041102    RESOLVEFUNC(SSL_new)
    9051103    RESOLVEFUNC(SSL_ctrl)
    9061104    RESOLVEFUNC(SSL_read)
    bool q_resolveOpenSslSymbols() 
    9131111    RESOLVEFUNC(SSL_get1_session)
    9141112    RESOLVEFUNC(SSL_get_session)
    9151113#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    916     RESOLVEFUNC(SSL_get_ex_new_index)
    9171114    RESOLVEFUNC(SSL_set_ex_data)
    9181115    RESOLVEFUNC(SSL_get_ex_data)
    9191116#endif
    bool q_resolveOpenSslSymbols() 
    9231120    RESOLVEFUNC(SSL_CTX_use_psk_identity_hint)
    9241121#endif
    9251122    RESOLVEFUNC(SSL_write)
    926 #ifndef OPENSSL_NO_SSL2
    927     RESOLVEFUNC(SSLv2_client_method)
    928 #endif
    929 #ifndef OPENSSL_NO_SSL3_METHOD
    930     RESOLVEFUNC(SSLv3_client_method)
    931 #endif
    932     RESOLVEFUNC(SSLv23_client_method)
    933     RESOLVEFUNC(TLSv1_client_method)
    934 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    935     RESOLVEFUNC(TLSv1_1_client_method)
    936     RESOLVEFUNC(TLSv1_2_client_method)
    937 #endif
    938 #ifndef OPENSSL_NO_SSL2
    939     RESOLVEFUNC(SSLv2_server_method)
    940 #endif
    941 #ifndef OPENSSL_NO_SSL3_METHOD
    942     RESOLVEFUNC(SSLv3_server_method)
    943 #endif
    944     RESOLVEFUNC(SSLv23_server_method)
    945     RESOLVEFUNC(TLSv1_server_method)
    946 #if OPENSSL_VERSION_NUMBER >= 0x10001000L
    947     RESOLVEFUNC(TLSv1_1_server_method)
    948     RESOLVEFUNC(TLSv1_2_server_method)
    949 #endif
    9501123    RESOLVEFUNC(X509_NAME_entry_count)
    9511124    RESOLVEFUNC(X509_NAME_get_entry)
    9521125    RESOLVEFUNC(X509_NAME_ENTRY_get_data)
    bool q_resolveOpenSslSymbols() 
    9621135    RESOLVEFUNC(X509_STORE_CTX_get_error)
    9631136    RESOLVEFUNC(X509_STORE_CTX_get_error_depth)
    9641137    RESOLVEFUNC(X509_STORE_CTX_get_current_cert)
    965     RESOLVEFUNC(X509_STORE_CTX_get_chain)
    9661138    RESOLVEFUNC(X509_cmp)
    9671139#ifndef SSLEAY_MACROS
    9681140    RESOLVEFUNC(X509_dup)
    9691141#endif
    9701142    RESOLVEFUNC(X509_print)
     1143    RESOLVEFUNC(X509_digest)
    9711144    RESOLVEFUNC(X509_EXTENSION_get_object)
    9721145    RESOLVEFUNC(X509_free)
    9731146    RESOLVEFUNC(X509_get_ext)
    bool q_resolveOpenSslSymbols() 
    9831156    RESOLVEFUNC(X509_check_issued)
    9841157    RESOLVEFUNC(X509_get_issuer_name)
    9851158    RESOLVEFUNC(X509_get_subject_name)
     1159    RESOLVEFUNC(X509_get_serialNumber)
    9861160    RESOLVEFUNC(X509_verify_cert)
    9871161    RESOLVEFUNC(d2i_X509)
    9881162    RESOLVEFUNC(i2d_X509)
    989 #ifdef SSLEAY_MACROS
    990     RESOLVEFUNC(i2d_DSAPrivateKey)
    991     RESOLVEFUNC(i2d_RSAPrivateKey)
    992     RESOLVEFUNC(d2i_DSAPrivateKey)
    993     RESOLVEFUNC(d2i_RSAPrivateKey)
    994 #endif
    995     RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf)
    996     RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
    9971163    RESOLVEFUNC(SSL_CTX_load_verify_locations)
    998     RESOLVEFUNC(SSLeay)
    999     RESOLVEFUNC(SSLeay_version)
    10001164    RESOLVEFUNC(i2d_SSL_SESSION)
    10011165    RESOLVEFUNC(d2i_SSL_SESSION)
    10021166#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
    bool q_resolveOpenSslSymbols() 
    10201184    RESOLVEFUNC(EC_KEY_new_by_curve_name)
    10211185    RESOLVEFUNC(EC_KEY_free)
    10221186    RESOLVEFUNC(EC_get_builtin_curves)
    1023 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
    1024     if (q_SSLeay() >= 0x10002000L)
    1025         RESOLVEFUNC(EC_curve_nist2nid)
    1026 #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
    10271187#endif // OPENSSL_NO_EC
    10281188    RESOLVEFUNC(PKCS12_parse)
    10291189    RESOLVEFUNC(d2i_PKCS12_bio)
    10301190    RESOLVEFUNC(PKCS12_free)
    10311191
     1192    symbolsResolved = true;
    10321193    delete libs.first;
    10331194    delete libs.second;
    1034     if (!_q_SSLeay || q_SSLeay() >= 0x10100000L) {
    1035         // OpenSSL 1.1 deprecated and removed SSLeay. We consider a failure to
    1036         // resolve this symbol as a failure to resolve symbols.
    1037         // The right operand of '||' above ... a bit of paranoia.
    1038         qCWarning(lcSsl, "Incompatible version of OpenSSL");
    1039         return false;
    1040     }
    1041 
    1042     symbolsResolved = true;
    1043 
    10441195    return true;
    10451196}
    10461197#endif // QT_CONFIG(library)
  • qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h

    diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h
    index b35a895d38112aac796f7b48f2bcabd88a7bf04b..796bf2d4f5982c92bccde5eaca51f041e4420eb6 100644
    a b  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2016 The Qt Company Ltd.
     3** Copyright (C) 2017 The Qt Company Ltd.
    44** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
    55** Contact: https://www.qt.io/licensing/
    66**
     
    5656#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H
    5757#define QSSLSOCKET_OPENSSL_SYMBOLS_P_H
    5858
     59
    5960//
    6061//  W A R N I N G
    6162//  -------------
    QT_BEGIN_NAMESPACE 
    215216
    216217#endif // !defined QT_LINKED_OPENSSL
    217218
     219#if QT_CONFIG(opensslv11)
     220#include "qsslsocket_openssl11_symbols_p.h"
     221#else
     222#include "qsslsocket_opensslpre11_symbols_p.h"
     223#endif // QT_CONFIG
     224
    218225bool q_resolveOpenSslSymbols();
    219226long q_ASN1_INTEGER_get(ASN1_INTEGER *a);
    220 unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
    221227int q_ASN1_STRING_length(ASN1_STRING *a);
    222228int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
    223229long q_BIO_ctrl(BIO *a, int b, long c, void *d);
    224230Q_AUTOTEST_EXPORT int q_BIO_free(BIO *a);
    225 Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a);
    226231BIO *q_BIO_new_mem_buf(void *a, int b);
    227232int q_BIO_read(BIO *a, void *b, int c);
    228 Q_AUTOTEST_EXPORT BIO_METHOD *q_BIO_s_mem();
    229233Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c);
    230234int q_BN_num_bits(const BIGNUM *a);
    231235#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w); 
    247251const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k);
    248252int q_EC_GROUP_get_degree(const EC_GROUP* g);
    249253#endif
    250 int q_CRYPTO_num_locks();
    251 void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
    252 void q_CRYPTO_set_id_callback(unsigned long (*a)());
    253 void q_CRYPTO_free(void *a);
    254254DSA *q_DSA_new();
    255255void q_DSA_free(DSA *a);
    256256X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c);
    257257char *q_ERR_error_string(unsigned long a, char *b);
    258258unsigned long q_ERR_get_error();
    259 void q_ERR_free_strings();
    260 void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
    261 void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
     259EVP_CIPHER_CTX *q_EVP_CIPHER_CTX_new();
     260void q_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);
    262261int q_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
    263262int q_EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
    264263int q_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *key, const unsigned char *iv, int enc);
     264int q_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc);
    265265int q_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
    266266int q_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
    267267const EVP_CIPHER *q_EVP_des_cbc();
    268268const EVP_CIPHER *q_EVP_des_ede3_cbc();
    269269const EVP_CIPHER *q_EVP_rc2_cbc();
     270const EVP_MD *q_EVP_sha1();
    270271int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
    271272Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
    272273int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
    int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned 
    310311int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d,
    311312                                  int e, pem_password_cb *f, void *g);
    312313#endif
    313 #endif
     314#endif // SSLEAY_MACROS
    314315Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
    315316DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d);
    316317RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d);
    void q_RAND_seed(const void *a, int b); 
    326327int q_RAND_status();
    327328RSA *q_RSA_new();
    328329void q_RSA_free(RSA *a);
    329 int q_sk_num(STACK *a);
    330 void q_sk_pop_free(STACK *a, void (*b)(void *));
    331 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    332 _STACK *q_sk_new_null();
    333 void q_sk_push(_STACK *st, void *data);
    334 void q_sk_free(_STACK *a);
    335 void * q_sk_value(STACK *a, int b);
    336 #else
    337 STACK *q_sk_new_null();
    338 void q_sk_push(STACK *st, char *data);
    339 void q_sk_free(STACK *a);
    340 char * q_sk_value(STACK *a, int b);
    341 #endif
    342330int q_SSL_accept(SSL *a);
    343331int q_SSL_clear(SSL *a);
    344 char *q_SSL_CIPHER_description(SSL_CIPHER *a, char *b, int c);
    345 int q_SSL_CIPHER_get_bits(SSL_CIPHER *a, int *b);
     332char *q_SSL_CIPHER_description(const SSL_CIPHER *a, char *b, int c);
     333int q_SSL_CIPHER_get_bits(const SSL_CIPHER *a, int *b);
    346334int q_SSL_connect(SSL *a);
    347335int q_SSL_CTX_check_private_key(const SSL_CTX *a);
    348336long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d);
    int q_SSL_get_error(SSL *a, int b); 
    374362STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
    375363X509 *q_SSL_get_peer_certificate(SSL *a);
    376364long q_SSL_get_verify_result(const SSL *a);
    377 int q_SSL_library_init();
    378 void q_SSL_load_error_strings();
    379365SSL *q_SSL_new(SSL_CTX *a);
    380366long q_SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
    381367int q_SSL_read(SSL *a, void *b, int c);
    void q_SSL_SESSION_free(SSL_SESSION *ses); 
    388374SSL_SESSION *q_SSL_get1_session(SSL *ssl);
    389375SSL_SESSION *q_SSL_get_session(const SSL *ssl);
    390376#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    391 int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
    392377int q_SSL_set_ex_data(SSL *ssl, int idx, void *arg);
    393378void *q_SSL_get_ex_data(const SSL *ssl, int idx);
    394379#endif
    typedef unsigned int (*q_psk_server_callback_t)(SSL *ssl, const char *identity, 
    399384void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback);
    400385int q_SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint);
    401386#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
    402 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
    403 #ifndef OPENSSL_NO_SSL2
    404 const SSL_METHOD *q_SSLv2_client_method();
    405 #endif
    406 #ifndef OPENSSL_NO_SSL3_METHOD
    407 const SSL_METHOD *q_SSLv3_client_method();
    408 #endif
    409 const SSL_METHOD *q_SSLv23_client_method();
    410 const SSL_METHOD *q_TLSv1_client_method();
    411 const SSL_METHOD *q_TLSv1_1_client_method();
    412 const SSL_METHOD *q_TLSv1_2_client_method();
    413 #ifndef OPENSSL_NO_SSL2
    414 const SSL_METHOD *q_SSLv2_server_method();
    415 #endif
    416 #ifndef OPENSSL_NO_SSL3_METHOD
    417 const SSL_METHOD *q_SSLv3_server_method();
    418 #endif
    419 const SSL_METHOD *q_SSLv23_server_method();
    420 const SSL_METHOD *q_TLSv1_server_method();
    421 const SSL_METHOD *q_TLSv1_1_server_method();
    422 const SSL_METHOD *q_TLSv1_2_server_method();
    423 #else
    424 #ifndef OPENSSL_NO_SSL2
    425 SSL_METHOD *q_SSLv2_client_method();
    426 #endif
    427 #ifndef OPENSSL_NO_SSL3_METHOD
    428 SSL_METHOD *q_SSLv3_client_method();
    429 #endif
    430 SSL_METHOD *q_SSLv23_client_method();
    431 SSL_METHOD *q_TLSv1_client_method();
    432 SSL_METHOD *q_TLSv1_1_client_method();
    433 SSL_METHOD *q_TLSv1_2_client_method();
    434 #ifndef OPENSSL_NO_SSL2
    435 SSL_METHOD *q_SSLv2_server_method();
    436 #endif
    437 #ifndef OPENSSL_NO_SSL3_METHOD
    438 SSL_METHOD *q_SSLv3_server_method();
    439 #endif
    440 SSL_METHOD *q_SSLv23_server_method();
    441 SSL_METHOD *q_TLSv1_server_method();
    442 SSL_METHOD *q_TLSv1_1_server_method();
    443 SSL_METHOD *q_TLSv1_2_server_method();
    444 #endif
    445387int q_SSL_write(SSL *a, const void *b, int c);
    446388int q_X509_cmp(X509 *a, X509 *b);
    447389#ifdef SSLEAY_MACROS
    void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); 
    452394X509 *q_X509_dup(X509 *a);
    453395#endif
    454396void q_X509_print(BIO *a, X509*b);
     397int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len);
    455398ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a);
    456399void q_X509_free(X509 *a);
    457400X509_EXTENSION *q_X509_get_ext(X509 *a, int b);
    int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b); 
    471414int q_X509_check_issued(X509 *a, X509 *b);
    472415X509_NAME *q_X509_get_issuer_name(X509 *a);
    473416X509_NAME *q_X509_get_subject_name(X509 *a);
     417ASN1_INTEGER *q_X509_get_serialNumber(X509 *a);
    474418int q_X509_verify_cert(X509_STORE_CTX *ctx);
    475419int q_X509_NAME_entry_count(X509_NAME *a);
    476420X509_NAME_ENTRY *q_X509_NAME_get_entry(X509_NAME *a,int b);
    int q_X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); 
    488432int q_X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
    489433int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
    490434X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
    491 STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
    492435
    493436// Diffie-Hellman support
    494437DH *q_DH_new();
    int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 
    522465PKCS12 *q_d2i_PKCS12_bio(BIO *bio, PKCS12 **pkcs12);
    523466void q_PKCS12_free(PKCS12 *pkcs12);
    524467
    525 
    526468#define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
    527469#define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
    528 #ifdef SSLEAY_MACROS
    529 int     q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
    530 int     q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
    531 RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
    532 DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
    533 #define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
    534         (RSA *)q_PEM_ASN1_read_bio( \
    535         (void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u)
    536 #define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
    537         (DSA *)q_PEM_ASN1_read_bio( \
    538         (void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u)
    539 #define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
    540         PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
    541                            bp,(char *)x,enc,kstr,klen,cb,u)
    542 #define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
    543         PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
    544                            bp,(char *)x,enc,kstr,klen,cb,u)
    545 #define q_PEM_read_bio_DHparams(bp, dh, cb, u) \
    546         (DH *)q_PEM_ASN1_read_bio( \
    547         (void *(*)(void**, const unsigned char**, long int))q_d2i_DHparams, PEM_STRING_DHPARAMS, bp, (void **)x, cb, u)
    548 #endif
    549 #define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
    550470#define q_SSL_CTX_set_mode(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
    551 #define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_sk_num)(st)
    552 #define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_sk_value)(st, i)
    553471#define q_sk_GENERAL_NAME_num(st) q_SKM_sk_num(GENERAL_NAME, (st))
    554472#define q_sk_GENERAL_NAME_value(st, i) q_SKM_sk_value(GENERAL_NAME, (st), (i))
    555473#define q_sk_X509_num(st) q_SKM_sk_num(X509, (st))
    DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); 
    558476#define q_sk_SSL_CIPHER_value(st, i) q_SKM_sk_value(SSL_CIPHER, (st), (i))
    559477#define q_SSL_CTX_add_extra_chain_cert(ctx,x509) \
    560478        q_SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
    561 #define q_X509_get_notAfter(x) X509_get_notAfter(x)
    562 #define q_X509_get_notBefore(x) X509_get_notBefore(x)
    563479#define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
    564480                                        (char *)(rsa))
    565481#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
    566482                                        (char *)(dsa))
    567483#define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf()
    568 void q_OPENSSL_add_all_algorithms_noconf();
    569 void q_OPENSSL_add_all_algorithms_conf();
    570484int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
    571 long q_SSLeay();
    572 const char *q_SSLeay_version(int type);
    573485int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
    574486SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
    575487
  • new file qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp

    diff --git a/qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp b/qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp
    new file mode 100644
    index 0000000000000000000000000000000000000000..e51888c5f2407eec914765fea174215da8a511cd
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 Governikus GmbH & Co. KG
     5** Contact: https://www.qt.io/licensing/
     6**
     7** This file is part of the QtNetwork module of the Qt Toolkit.
     8**
     9** $QT_BEGIN_LICENSE:LGPL$
     10** Commercial License Usage
     11** Licensees holding valid commercial Qt licenses may use this file in
     12** accordance with the commercial license agreement provided with the
     13** Software or, alternatively, in accordance with the terms contained in
     14** a written agreement between you and The Qt Company. For licensing terms
     15** and conditions see https://www.qt.io/terms-conditions. For further
     16** information use the contact form at https://www.qt.io/contact-us.
     17**
     18** GNU Lesser General Public License Usage
     19** Alternatively, this file may be used under the terms of the GNU Lesser
     20** General Public License version 3 as published by the Free Software
     21** Foundation and appearing in the file LICENSE.LGPL3 included in the
     22** packaging of this file. Please review the following information to
     23** ensure the GNU Lesser General Public License version 3 requirements
     24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     25**
     26** GNU General Public License Usage
     27** Alternatively, this file may be used under the terms of the GNU
     28** General Public License version 2.0 or (at your option) the GNU General
     29** Public license version 3 or any later version approved by the KDE Free
     30** Qt Foundation. The licenses are as published by the Free Software
     31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     32** included in the packaging of this file. Please review the following
     33** information to ensure the GNU General Public License requirements will
     34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     35** https://www.gnu.org/licenses/gpl-3.0.html.
     36**
     37** $QT_END_LICENSE$
     38**
     39****************************************************************************/
     40
     41/****************************************************************************
     42**
     43** In addition, as a special exception, the copyright holders listed above give
     44** permission to link the code of its release of Qt with the OpenSSL project's
     45** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
     46** same license as the original version), and distribute the linked executables.
     47**
     48** You must comply with the GNU General Public License version 2 in all
     49** respects for all of the code used other than the "OpenSSL" code.  If you
     50** modify this file, you may extend this exception to your version of the file,
     51** but you are not obligated to do so.  If you do not wish to do so, delete
     52** this exception statement from your version of this file.
     53**
     54****************************************************************************/
     55
     56//#define QT_DECRYPT_SSL_TRAFFIC
     57
     58#include "qssl_p.h"
     59#include "qsslsocket_openssl_p.h"
     60#include "qsslsocket_openssl_symbols_p.h"
     61#include "qsslsocket.h"
     62#include "qsslkey.h"
     63
     64#include <QtCore/qdebug.h>
     65#include <QtCore/qdir.h>
     66#include <QtCore/qdiriterator.h>
     67#include <QtCore/qthread.h>
     68#include <QtCore/qfile.h>
     69#include <QtCore/qmutex.h>
     70#include <QtCore/qlibrary.h>
     71
     72QT_BEGIN_NAMESPACE
     73
     74/* \internal
     75
     76    From OpenSSL's thread(3) manual page:
     77
     78    OpenSSL can safely be used in multi-threaded applications provided that at
     79    least two callback functions are set.
     80
     81    locking_function(int mode, int n, const char *file, int line) is needed to
     82    perform locking on shared data structures.  (Note that OpenSSL uses a
     83    number of global data structures that will be implicitly shared
     84    whenever multiple threads use OpenSSL.)  Multi-threaded
     85    applications will crash at random if it is not set.  ...
     86    ...
     87    id_function(void) is a function that returns a thread ID. It is not
     88    needed on Windows nor on platforms where getpid() returns a different
     89    ID for each thread (most notably Linux)
     90*/
     91
     92class QOpenSslLocks
     93{
     94public:
     95    QOpenSslLocks()
     96        : initLocker(QMutex::Recursive),
     97          locksLocker(QMutex::Recursive)
     98    {
     99        QMutexLocker locker(&locksLocker);
     100        int numLocks = q_CRYPTO_num_locks();
     101        locks = new QMutex *[numLocks];
     102        memset(locks, 0, numLocks * sizeof(QMutex *));
     103    }
     104    ~QOpenSslLocks()
     105    {
     106        QMutexLocker locker(&locksLocker);
     107        for (int i = 0; i < q_CRYPTO_num_locks(); ++i)
     108            delete locks[i];
     109        delete [] locks;
     110
     111        QSslSocketPrivate::deinitialize();
     112    }
     113    QMutex *lock(int num)
     114    {
     115        QMutexLocker locker(&locksLocker);
     116        QMutex *tmp = locks[num];
     117        if (!tmp)
     118            tmp = locks[num] = new QMutex(QMutex::Recursive);
     119        return tmp;
     120    }
     121
     122    QMutex *globalLock()
     123    {
     124        return &locksLocker;
     125    }
     126
     127    QMutex *initLock()
     128    {
     129        return &initLocker;
     130    }
     131
     132private:
     133    QMutex initLocker;
     134    QMutex locksLocker;
     135    QMutex **locks;
     136};
     137
     138Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
     139
     140extern "C" {
     141static void locking_function(int mode, int lockNumber, const char *, int)
     142{
     143    QMutex *mutex = openssl_locks()->lock(lockNumber);
     144
     145    // Lock or unlock it
     146    if (mode & CRYPTO_LOCK)
     147        mutex->lock();
     148    else
     149        mutex->unlock();
     150}
     151static unsigned long id_function()
     152{
     153    return (quintptr)QThread::currentThreadId();
     154}
     155
     156} // extern "C"
     157
     158static void q_OpenSSL_add_all_algorithms_safe()
     159{
     160#ifdef Q_OS_WIN
     161    // Prior to version 1.0.1m an attempt to call OpenSSL_add_all_algorithms on
     162    // Windows could result in 'exit' call from OPENSSL_config (QTBUG-43843).
     163    // We can predict this and avoid OPENSSL_add_all_algorithms call.
     164    // From OpenSSL docs:
     165    // "An application does not need to add algorithms to use them explicitly,
     166    // for example by EVP_sha1(). It just needs to add them if it (or any of
     167    // the functions it calls) needs to lookup algorithms.
     168    // The cipher and digest lookup functions are used in many parts of the
     169    // library. If the table is not initialized several functions will
     170    // misbehave and complain they cannot find algorithms. This includes the
     171    // PEM, PKCS#12, SSL and S/MIME libraries. This is a common query in
     172    // the OpenSSL mailing lists."
     173    //
     174    // Anyway, as a result, we chose not to call this function if it would exit.
     175
     176    if (q_SSLeay() < 0x100010DFL)
     177    {
     178        // Now, before we try to call it, check if an attempt to open config file
     179        // will result in exit:
     180        if (char *confFileName = q_CONF_get1_default_config_file()) {
     181            BIO *confFile = q_BIO_new_file(confFileName, "r");
     182            const auto lastError = q_ERR_peek_last_error();
     183            q_CRYPTO_free(confFileName);
     184            if (confFile) {
     185                q_BIO_free(confFile);
     186            } else {
     187                q_ERR_clear_error();
     188                if (ERR_GET_REASON(lastError) == ERR_R_SYS_LIB) {
     189                    qCWarning(lcSsl, "failed to open openssl.conf file");
     190                    return;
     191                }
     192            }
     193        }
     194    }
     195#endif // Q_OS_WIN
     196
     197    q_OpenSSL_add_all_algorithms();
     198}
     199
     200
     201/*!
     202    \internal
     203*/
     204void QSslSocketPrivate::deinitialize()
     205{
     206    q_CRYPTO_set_id_callback(0);
     207    q_CRYPTO_set_locking_callback(0);
     208    q_ERR_free_strings();
     209}
     210
     211
     212bool QSslSocketPrivate::ensureLibraryLoaded()
     213{
     214    if (!q_resolveOpenSslSymbols())
     215        return false;
     216
     217    // Check if the library itself needs to be initialized.
     218    QMutexLocker locker(openssl_locks()->initLock());
     219
     220    if (!s_libraryLoaded) {
     221        s_libraryLoaded = true;
     222
     223        // Initialize OpenSSL.
     224        q_CRYPTO_set_id_callback(id_function);
     225        q_CRYPTO_set_locking_callback(locking_function);
     226        if (q_SSL_library_init() != 1)
     227            return false;
     228        q_SSL_load_error_strings();
     229        q_OpenSSL_add_all_algorithms_safe();
     230
     231#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     232        if (q_SSLeay() >= 0x10001000L)
     233            QSslSocketBackendPrivate::s_indexForSSLExtraData = q_SSL_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
     234#endif
     235
     236        // Initialize OpenSSL's random seed.
     237        if (!q_RAND_status()) {
     238            qWarning("Random number generator not seeded, disabling SSL support");
     239            return false;
     240        }
     241    }
     242    return true;
     243}
     244
     245void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
     246{
     247    QMutexLocker locker(openssl_locks()->initLock());
     248    if (s_loadedCiphersAndCerts)
     249        return;
     250    s_loadedCiphersAndCerts = true;
     251
     252    resetDefaultCiphers();
     253    resetDefaultEllipticCurves();
     254
     255#if QT_CONFIG(library)
     256    //load symbols needed to receive certificates from system store
     257#if defined(Q_OS_WIN)
     258    HINSTANCE hLib = LoadLibraryW(L"Crypt32");
     259    if (hLib) {
     260        ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW");
     261        ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore");
     262        ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore");
     263        if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
     264            qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen
     265    } else {
     266        qCWarning(lcSsl, "could not load crypt32 library"); // should never happen
     267    }
     268#elif defined(Q_OS_QNX)
     269    s_loadRootCertsOnDemand = true;
     270#elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
     271    // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
     272    QList<QByteArray> dirs = unixRootCertDirectories();
     273    QStringList symLinkFilter;
     274    symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]");
     275    for (int a = 0; a < dirs.count(); ++a) {
     276        QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
     277        if (iterator.hasNext()) {
     278            s_loadRootCertsOnDemand = true;
     279            break;
     280        }
     281    }
     282#endif
     283#endif // QT_CONFIG(library)
     284    // if on-demand loading was not enabled, load the certs now
     285    if (!s_loadRootCertsOnDemand)
     286        setDefaultCaCertificates(systemCaCertificates());
     287#ifdef Q_OS_WIN
     288    //Enabled for fetching additional root certs from windows update on windows 6+
     289    //This flag is set false by setDefaultCaCertificates() indicating the app uses
     290    //its own cert bundle rather than the system one.
     291    //Same logic that disables the unix on demand cert loading.
     292    //Unlike unix, we do preload the certificates from the cert store.
     293    if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0)
     294        s_loadRootCertsOnDemand = true;
     295#endif
     296}
     297
     298long QSslSocketPrivate::sslLibraryVersionNumber()
     299{
     300    if (!supportsSsl())
     301        return 0;
     302
     303    return q_SSLeay();
     304}
     305
     306QString QSslSocketPrivate::sslLibraryVersionString()
     307{
     308    if (!supportsSsl())
     309        return QString();
     310
     311    const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
     312    if (!versionString)
     313        return QString();
     314
     315    return QString::fromLatin1(versionString);
     316}
     317
     318void QSslSocketBackendPrivate::continueHandshake()
     319{
     320    Q_Q(QSslSocket);
     321    // if we have a max read buffer size, reset the plain socket's to match
     322    if (readBufferMaxSize)
     323        plainSocket->setReadBufferSize(readBufferMaxSize);
     324
     325    if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL))
     326        configuration.peerSessionShared = true;
     327
     328#ifdef QT_DECRYPT_SSL_TRAFFIC
     329    if (ssl->session && ssl->s3) {
     330        const char *mk = reinterpret_cast<const char *>(ssl->session->master_key);
     331        QByteArray masterKey(mk, ssl->session->master_key_length);
     332        const char *random = reinterpret_cast<const char *>(ssl->s3->client_random);
     333        QByteArray clientRandom(random, SSL3_RANDOM_SIZE);
     334
     335        // different format, needed for e.g. older Wireshark versions:
     336//        const char *sid = reinterpret_cast<const char *>(ssl->session->session_id);
     337//        QByteArray sessionID(sid, ssl->session->session_id_length);
     338//        QByteArray debugLineRSA("RSA Session-ID:");
     339//        debugLineRSA.append(sessionID.toHex().toUpper());
     340//        debugLineRSA.append(" Master-Key:");
     341//        debugLineRSA.append(masterKey.toHex().toUpper());
     342//        debugLineRSA.append("\n");
     343
     344        QByteArray debugLineClientRandom("CLIENT_RANDOM ");
     345        debugLineClientRandom.append(clientRandom.toHex().toUpper());
     346        debugLineClientRandom.append(" ");
     347        debugLineClientRandom.append(masterKey.toHex().toUpper());
     348        debugLineClientRandom.append("\n");
     349
     350        QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
     351        QFile file(sslKeyFile);
     352        if (!file.open(QIODevice::Append))
     353            qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
     354        if (!file.write(debugLineClientRandom))
     355            qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
     356        file.close();
     357    } else {
     358        qCWarning(lcSsl, "could not decrypt SSL traffic");
     359    }
     360#endif
     361
     362    // Cache this SSL session inside the QSslContext
     363    if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) {
     364        if (!sslContextPointer->cacheSession(ssl)) {
     365            sslContextPointer.clear(); // we could not cache the session
     366        } else {
     367            // Cache the session for permanent usage as well
     368            if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) {
     369                if (!sslContextPointer->sessionASN1().isEmpty())
     370                    configuration.sslSession = sslContextPointer->sessionASN1();
     371                configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint();
     372            }
     373        }
     374    }
     375
     376#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG)
     377
     378    configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
     379    if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) {
     380        // we could not agree -> be conservative and use HTTP/1.1
     381        configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1");
     382    } else {
     383        const unsigned char *proto = 0;
     384        unsigned int proto_len = 0;
     385#if OPENSSL_VERSION_NUMBER >= 0x10002000L
     386        if (q_SSLeay() >= 0x10002000L) {
     387            q_SSL_get0_alpn_selected(ssl, &proto, &proto_len);
     388            if (proto_len && mode == QSslSocket::SslClientMode) {
     389                // Client does not have a callback that sets it ...
     390                configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
     391            }
     392        }
     393
     394        if (!proto_len) { // Test if NPN was more lucky ...
     395#else
     396        {
     397#endif
     398            q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
     399        }
     400
     401        if (proto_len)
     402            configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
     403        else
     404            configuration.nextNegotiatedProtocol.clear();
     405    }
     406#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
     407
     408#if OPENSSL_VERSION_NUMBER >= 0x10002000L
     409    if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) {
     410        EVP_PKEY *key;
     411        if (q_SSL_get_server_tmp_key(ssl, &key))
     412            configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
     413    }
     414#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
     415
     416    connectionEncrypted = true;
     417    emit q->encrypted();
     418    if (autoStartHandshake && pendingClose) {
     419        pendingClose = false;
     420        q->disconnectFromHost();
     421    }
     422}
     423
     424QT_END_NAMESPACE
  • new file qtbase/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h

    diff --git a/qtbase/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
    new file mode 100644
    index 0000000000000000000000000000000000000000..9686d22b98c16386568976f8e6d8c1b9b9e18240
    - +  
     1/****************************************************************************
     2**
     3** Copyright (C) 2017 The Qt Company Ltd.
     4** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
     5** Contact: https://www.qt.io/licensing/
     6**
     7** This file is part of the QtNetwork module of the Qt Toolkit.
     8**
     9** $QT_BEGIN_LICENSE:LGPL$
     10** Commercial License Usage
     11** Licensees holding valid commercial Qt licenses may use this file in
     12** accordance with the commercial license agreement provided with the
     13** Software or, alternatively, in accordance with the terms contained in
     14** a written agreement between you and The Qt Company. For licensing terms
     15** and conditions see https://www.qt.io/terms-conditions. For further
     16** information use the contact form at https://www.qt.io/contact-us.
     17**
     18** GNU Lesser General Public License Usage
     19** Alternatively, this file may be used under the terms of the GNU Lesser
     20** General Public License version 3 as published by the Free Software
     21** Foundation and appearing in the file LICENSE.LGPL3 included in the
     22** packaging of this file. Please review the following information to
     23** ensure the GNU Lesser General Public License version 3 requirements
     24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
     25**
     26** GNU General Public License Usage
     27** Alternatively, this file may be used under the terms of the GNU
     28** General Public License version 2.0 or (at your option) the GNU General
     29** Public license version 3 or any later version approved by the KDE Free
     30** Qt Foundation. The licenses are as published by the Free Software
     31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
     32** included in the packaging of this file. Please review the following
     33** information to ensure the GNU General Public License requirements will
     34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
     35** https://www.gnu.org/licenses/gpl-3.0.html.
     36**
     37** $QT_END_LICENSE$
     38**
     39****************************************************************************/
     40
     41/****************************************************************************
     42**
     43** In addition, as a special exception, the copyright holders listed above give
     44** permission to link the code of its release of Qt with the OpenSSL project's
     45** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
     46** same license as the original version), and distribute the linked executables.
     47**
     48** You must comply with the GNU General Public License version 2 in all
     49** respects for all of the code used other than the "OpenSSL" code.  If you
     50** modify this file, you may extend this exception to your version of the file,
     51** but you are not obligated to do so.  If you do not wish to do so, delete
     52** this exception statement from your version of this file.
     53**
     54****************************************************************************/
     55
     56
     57#ifndef QSSLSOCKET_OPENSSLPRE11_SYMBOLS_P_H
     58#define QSSLSOCKET_OPENSSLPRE11_SYMBOLS_P_H
     59
     60//
     61//  W A R N I N G
     62//  -------------
     63//
     64// This file is not part of the Qt API. It exists purely as an
     65// implementation detail. This header file may change from version to
     66// version without notice, or even be removed.
     67//
     68// We mean it.
     69//
     70
     71// Note: this file does not have QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, it's done
     72// in qsslsocket_openssl_symbols_p.h.
     73
     74#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H
     75#error "You are not supposed to use this header file, include qsslsocket_openssl_symbols_p.h instead"
     76#endif
     77
     78unsigned char * q_ASN1_STRING_data(ASN1_STRING *a);
     79BIO *q_BIO_new_file(const char *filename, const char *mode);
     80void q_ERR_clear_error();
     81Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a);
     82Q_AUTOTEST_EXPORT BIO_METHOD *q_BIO_s_mem();
     83int q_CRYPTO_num_locks();
     84void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
     85void q_CRYPTO_set_id_callback(unsigned long (*a)());
     86void q_CRYPTO_free(void *a);
     87unsigned long q_ERR_peek_last_error();
     88void q_ERR_free_strings();
     89void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
     90void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
     91
     92#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     93typedef _STACK STACK;
     94#endif
     95
     96// The typedef we use to make our pre 1.1 code look more like 1.1 (less ifdefs).
     97typedef STACK OPENSSL_STACK;
     98
     99// We resolve q_sk_ functions, but use q_OPENSSL_sk_ macros in code to reduce
     100// the amount of #ifdefs.
     101int q_sk_num(STACK *a);
     102#define q_OPENSSL_sk_num(a) q_sk_num(a)
     103void q_sk_pop_free(STACK *a, void (*b)(void *));
     104#define q_OPENSSL_sk_pop_free(a, b) q_sk_pop_free(a, b)
     105STACK *q_sk_new_null();
     106#define q_OPENSSL_sk_new_null() q_sk_new_null()
     107
     108void q_sk_free(STACK *a);
     109
     110// Just a name alias (not a function call expression) since in code we take an
     111// address of this:
     112#define q_OPENSSL_sk_free q_sk_free
     113
     114#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     115void *q_sk_value(STACK *a, int b);
     116void q_sk_push(STACK *st, void *data);
     117#else
     118char *q_sk_value(STACK *a, int b);
     119void q_sk_push(STACK *st, char *data);
     120#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
     121
     122#define q_OPENSSL_sk_value(a, b) q_sk_value(a, b)
     123#define q_OPENSSL_sk_push(st, data) q_sk_push(st, data)
     124
     125#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     126SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a);
     127#else
     128SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a);
     129#endif
     130
     131int q_SSL_library_init();
     132void q_SSL_load_error_strings();
     133
     134#if OPENSSL_VERSION_NUMBER >= 0x10001000L
     135int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
     136#endif
     137
     138#if OPENSSL_VERSION_NUMBER >= 0x10000000L
     139#ifndef OPENSSL_NO_SSL2
     140const SSL_METHOD *q_SSLv2_client_method();
     141#endif
     142#ifndef OPENSSL_NO_SSL3_METHOD
     143const SSL_METHOD *q_SSLv3_client_method();
     144#endif
     145const SSL_METHOD *q_SSLv23_client_method();
     146const SSL_METHOD *q_TLSv1_client_method();
     147const SSL_METHOD *q_TLSv1_1_client_method();
     148const SSL_METHOD *q_TLSv1_2_client_method();
     149#ifndef OPENSSL_NO_SSL2
     150const SSL_METHOD *q_SSLv2_server_method();
     151#endif
     152#ifndef OPENSSL_NO_SSL3_METHOD
     153const SSL_METHOD *q_SSLv3_server_method();
     154#endif
     155const SSL_METHOD *q_SSLv23_server_method();
     156const SSL_METHOD *q_TLSv1_server_method();
     157const SSL_METHOD *q_TLSv1_1_server_method();
     158const SSL_METHOD *q_TLSv1_2_server_method();
     159#else
     160#ifndef OPENSSL_NO_SSL2
     161SSL_METHOD *q_SSLv2_client_method();
     162#endif
     163#ifndef OPENSSL_NO_SSL3_METHOD
     164SSL_METHOD *q_SSLv3_client_method();
     165#endif
     166SSL_METHOD *q_SSLv23_client_method();
     167SSL_METHOD *q_TLSv1_client_method();
     168SSL_METHOD *q_TLSv1_1_client_method();
     169SSL_METHOD *q_TLSv1_2_client_method();
     170#ifndef OPENSSL_NO_SSL2
     171SSL_METHOD *q_SSLv2_server_method();
     172#endif
     173#ifndef OPENSSL_NO_SSL3_METHOD
     174SSL_METHOD *q_SSLv3_server_method();
     175#endif
     176SSL_METHOD *q_SSLv23_server_method();
     177SSL_METHOD *q_TLSv1_server_method();
     178SSL_METHOD *q_TLSv1_1_server_method();
     179SSL_METHOD *q_TLSv1_2_server_method();
     180#endif
     181
     182STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
     183
     184#ifdef SSLEAY_MACROS
     185int     q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
     186int     q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
     187RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
     188DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
     189#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
     190        (RSA *)q_PEM_ASN1_read_bio( \
     191        (void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u)
     192#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
     193        (DSA *)q_PEM_ASN1_read_bio( \
     194        (void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u)
     195#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
     196        PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
     197                           bp,(char *)x,enc,kstr,klen,cb,u)
     198#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
     199        PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
     200                           bp,(char *)x,enc,kstr,klen,cb,u)
     201#define q_PEM_read_bio_DHparams(bp, dh, cb, u) \
     202        (DH *)q_PEM_ASN1_read_bio( \
     203        (void *(*)(void**, const unsigned char**, long int))q_d2i_DHparams, PEM_STRING_DHPARAMS, bp, (void **)x, cb, u)
     204#endif // SSLEAY_MACROS
     205
     206#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
     207#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_sk_num)(st)
     208#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_sk_value)(st, i)
     209#define q_X509_getm_notAfter(x) X509_get_notAfter(x)
     210#define q_X509_getm_notBefore(x) X509_get_notBefore(x)
     211
     212// "Forward compatibility" with OpenSSL 1.1 (to save on #if-ery elsewhere):
     213#define q_X509_get_version(x509) q_ASN1_INTEGER_get((x509)->cert_info->version)
     214#define q_ASN1_STRING_get0_data(x) q_ASN1_STRING_data(x)
     215#define q_EVP_PKEY_base_id(pkey) ((pkey)->type)
     216#define q_X509_get_pubkey(x509) q_X509_PUBKEY_get((x509)->cert_info->key)
     217#define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint)
     218#define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n)
     219#define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p)
     220#define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c))
     221
     222char *q_CONF_get1_default_config_file();
     223void q_OPENSSL_add_all_algorithms_noconf();
     224void q_OPENSSL_add_all_algorithms_conf();
     225
     226long q_SSLeay();
     227const char *q_SSLeay_version(int type);
     228
     229
     230#endif // QSSLSOCKET_OPENSSL_PRE11_SYMBOLS_P_H
  • qtbase/src/network/ssl/ssl.pri

    diff --git a/qtbase/src/network/ssl/ssl.pri b/qtbase/src/network/ssl/ssl.pri
    index d2b0c2d60d30e2604eaf1519a6c2bde571a2e4f6..2783effaf123120f9dfea87b11a5f4262faea504 100644
    a b qtConfig(ssl) { 
    6060        HEADERS += ssl/qsslcontext_openssl_p.h \
    6161                   ssl/qsslsocket_openssl_p.h \
    6262                   ssl/qsslsocket_openssl_symbols_p.h
    63         SOURCES += ssl/qsslcertificate_openssl.cpp \
    64                    ssl/qsslcontext_openssl.cpp \
     63        SOURCES += ssl/qsslsocket_openssl_symbols.cpp \
    6564                   ssl/qssldiffiehellmanparameters_openssl.cpp \
     65                   ssl/qsslcertificate_openssl.cpp \
    6666                   ssl/qsslellipticcurve_openssl.cpp \
    6767                   ssl/qsslkey_openssl.cpp \
    6868                   ssl/qsslsocket_openssl.cpp \
    69                    ssl/qsslsocket_openssl_symbols.cpp
     69                   ssl/qsslcontext_openssl.cpp
     70
     71        qtConfig(opensslv11) {
     72            HEADERS += ssl/qsslsocket_openssl11_symbols_p.h
     73            SOURCES += ssl/qsslsocket_openssl11.cpp \
     74                       ssl/qsslcontext_openssl11.cpp
     75
     76            QMAKE_CXXFLAGS += -DOPENSSL_API_COMPAT=0x10100000L
     77        } else {
     78            HEADERS += ssl/qsslsocket_opensslpre11_symbols_p.h
     79            SOURCES += ssl/qsslsocket_opensslpre11.cpp \
     80                       ssl/qsslcontext_opensslpre11.cpp
     81        }
    7082
    7183        darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
    7284