util/src/network/ssl/qsslsocket_openssl.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 //#define QSSLSOCKET_DEBUG
       
    43 
       
    44 #include "qsslsocket_openssl_p.h"
       
    45 #include "qsslsocket_openssl_symbols_p.h"
       
    46 #include "qsslsocket.h"
       
    47 #include "qsslcertificate_p.h"
       
    48 #include "qsslcipher_p.h"
       
    49 
       
    50 #include <QtCore/qdatetime.h>
       
    51 #include <QtCore/qdebug.h>
       
    52 #include <QtCore/qdir.h>
       
    53 #include <QtCore/qdiriterator.h>
       
    54 #include <QtCore/qfile.h>
       
    55 #include <QtCore/qfileinfo.h>
       
    56 #include <QtCore/qmutex.h>
       
    57 #include <QtCore/qthread.h>
       
    58 #include <QtCore/qurl.h>
       
    59 #include <QtCore/qvarlengtharray.h>
       
    60 
       
    61 static void initNetworkResources()
       
    62 {
       
    63     // Initialize resources
       
    64     Q_INIT_RESOURCE(network);
       
    65 }
       
    66 
       
    67 QT_BEGIN_NAMESPACE
       
    68 
       
    69 // Useful defines
       
    70 #define SSL_ERRORSTR() QString::fromLocal8Bit(q_ERR_error_string(q_ERR_get_error(), NULL))
       
    71 
       
    72 /* \internal
       
    73 
       
    74     From OpenSSL's thread(3) manual page:
       
    75 
       
    76     OpenSSL can safely be used in multi-threaded applications provided that at
       
    77     least two callback functions are set.
       
    78 
       
    79     locking_function(int mode, int n, const char *file, int line) is needed to
       
    80     perform locking on shared data structures.  (Note that OpenSSL uses a
       
    81     number of global data structures that will be implicitly shared
       
    82     when-whenever ever multiple threads use OpenSSL.)  Multi-threaded
       
    83     applications will crash at random if it is not set.  ...
       
    84     ...
       
    85     id_function(void) is a function that returns a thread ID. It is not
       
    86     needed on Windows nor on platforms where getpid() returns a different
       
    87     ID for each thread (most notably Linux)
       
    88 */
       
    89 class QOpenSslLocks
       
    90 {
       
    91 public:
       
    92     inline QOpenSslLocks()
       
    93         : initLocker(QMutex::Recursive),
       
    94           locksLocker(QMutex::Recursive)
       
    95     {
       
    96         QMutexLocker locker(&locksLocker);
       
    97         int numLocks = q_CRYPTO_num_locks();
       
    98         locks = new QMutex *[numLocks];
       
    99         memset(locks, 0, numLocks * sizeof(QMutex *));
       
   100     }
       
   101     inline ~QOpenSslLocks()
       
   102     {
       
   103         QMutexLocker locker(&locksLocker);
       
   104         for (int i = 0; i < q_CRYPTO_num_locks(); ++i)
       
   105             delete locks[i];
       
   106         delete [] locks;
       
   107 
       
   108         QSslSocketPrivate::deinitialize();
       
   109     }
       
   110     inline QMutex *lock(int num)
       
   111     {
       
   112         QMutexLocker locker(&locksLocker);
       
   113         QMutex *tmp = locks[num];
       
   114         if (!tmp)
       
   115             tmp = locks[num] = new QMutex(QMutex::Recursive);
       
   116         return tmp;
       
   117     }
       
   118 
       
   119     QMutex *globalLock()
       
   120     {
       
   121         return &locksLocker;
       
   122     }
       
   123 
       
   124     QMutex *initLock()
       
   125     {
       
   126         return &initLocker;
       
   127     }
       
   128 
       
   129 private:
       
   130     QMutex initLocker;
       
   131     QMutex locksLocker;
       
   132     QMutex **locks;
       
   133 };
       
   134 Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
       
   135 
       
   136 extern "C" {
       
   137 static void locking_function(int mode, int lockNumber, const char *, int)
       
   138 {
       
   139     QMutex *mutex = openssl_locks()->lock(lockNumber);
       
   140 
       
   141     // Lock or unlock it
       
   142     if (mode & CRYPTO_LOCK)
       
   143         mutex->lock();
       
   144     else
       
   145         mutex->unlock();
       
   146 }
       
   147 static unsigned long id_function()
       
   148 {
       
   149     return (unsigned long)QThread::currentThreadId();
       
   150 }
       
   151 } // extern "C"
       
   152 
       
   153 QSslSocketBackendPrivate::QSslSocketBackendPrivate()
       
   154     : ssl(0),
       
   155       ctx(0),
       
   156       readBio(0),
       
   157       writeBio(0),
       
   158       session(0)
       
   159 {
       
   160     // Calls SSL_library_init().
       
   161     ensureInitialized();
       
   162 }
       
   163 
       
   164 QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
       
   165 {
       
   166 }
       
   167 
       
   168 QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher)
       
   169 {
       
   170     QSslCipher ciph;
       
   171 
       
   172     char buf [256];
       
   173     QString descriptionOneLine = QString::fromLatin1(q_SSL_CIPHER_description(cipher, buf, sizeof(buf)));
       
   174 
       
   175     QStringList descriptionList = descriptionOneLine.split(QLatin1String(" "), QString::SkipEmptyParts);
       
   176     if (descriptionList.size() > 5) {
       
   177         // ### crude code.
       
   178         ciph.d->isNull = false;
       
   179         ciph.d->name = descriptionList.at(0);
       
   180 
       
   181         QString protoString = descriptionList.at(1);
       
   182         ciph.d->protocolString = protoString;
       
   183         ciph.d->protocol = QSsl::UnknownProtocol;
       
   184         if (protoString == QLatin1String("SSLv3"))
       
   185             ciph.d->protocol = QSsl::SslV3;
       
   186         else if (protoString == QLatin1String("SSLv2"))
       
   187             ciph.d->protocol = QSsl::SslV2;
       
   188         else if (protoString == QLatin1String("TLSv1"))
       
   189             ciph.d->protocol = QSsl::TlsV1;
       
   190         
       
   191         if (descriptionList.at(2).startsWith(QLatin1String("Kx=")))
       
   192             ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3);
       
   193         if (descriptionList.at(3).startsWith(QLatin1String("Au=")))
       
   194             ciph.d->authenticationMethod = descriptionList.at(3).mid(3);
       
   195         if (descriptionList.at(4).startsWith(QLatin1String("Enc=")))
       
   196             ciph.d->encryptionMethod = descriptionList.at(4).mid(4);
       
   197         ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == QLatin1String("export"));
       
   198 
       
   199         ciph.d->bits = cipher->strength_bits;
       
   200         ciph.d->supportedBits = cipher->alg_bits;
       
   201 
       
   202     }
       
   203     return ciph;
       
   204 }
       
   205 
       
   206 // ### This list is shared between all threads, and protected by a
       
   207 // mutex. Investigate using thread local storage instead.
       
   208 struct QSslErrorList
       
   209 {
       
   210     QMutex mutex;
       
   211     QList<QPair<int, int> > errors;
       
   212 };
       
   213 Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
       
   214 static int q_X509Callback(int ok, X509_STORE_CTX *ctx)
       
   215 {
       
   216     if (!ok) {
       
   217         // Store the error and at which depth the error was detected.
       
   218         _q_sslErrorList()->errors << qMakePair<int, int>(ctx->error, ctx->error_depth);
       
   219     }
       
   220     // Always return OK to allow verification to continue. We're handle the
       
   221     // errors gracefully after collecting all errors, after verification has
       
   222     // completed.
       
   223     return 1;
       
   224 }
       
   225 
       
   226 bool QSslSocketBackendPrivate::initSslContext()
       
   227 {
       
   228     Q_Q(QSslSocket);
       
   229 
       
   230     // Create and initialize SSL context. Accept SSLv2, SSLv3 and TLSv1.
       
   231     bool client = (mode == QSslSocket::SslClientMode);
       
   232 
       
   233     bool reinitialized = false;
       
   234 init_context:
       
   235     switch (configuration.protocol) {
       
   236     case QSsl::SslV2:
       
   237         ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
       
   238         break;
       
   239     case QSsl::SslV3:
       
   240         ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
       
   241         break;
       
   242     case QSsl::AnyProtocol:
       
   243     default:
       
   244         ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
       
   245         break;
       
   246     case QSsl::TlsV1:
       
   247         ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
       
   248         break;
       
   249     }
       
   250     if (!ctx) {
       
   251         // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
       
   252         // by re-initializing the library.
       
   253         if (!reinitialized) {
       
   254             reinitialized = true;
       
   255             if (q_SSL_library_init() == 1)
       
   256                 goto init_context;
       
   257         }
       
   258 
       
   259         // ### Bad error code
       
   260         q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg(SSL_ERRORSTR()));
       
   261         q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   262         emit q->error(QAbstractSocket::UnknownSocketError);
       
   263         return false;
       
   264     }
       
   265 
       
   266     // Enable all bug workarounds.
       
   267     q_SSL_CTX_set_options(ctx, SSL_OP_ALL);
       
   268 
       
   269     // Initialize ciphers
       
   270     QByteArray cipherString;
       
   271     int first = true;
       
   272     QList<QSslCipher> ciphers = configuration.ciphers;
       
   273     if (ciphers.isEmpty())
       
   274         ciphers = defaultCiphers();
       
   275     foreach (const QSslCipher &cipher, ciphers) {
       
   276         if (first)
       
   277             first = false;
       
   278         else
       
   279             cipherString.append(':');
       
   280         cipherString.append(cipher.name().toLatin1());
       
   281     }
       
   282 
       
   283     if (!q_SSL_CTX_set_cipher_list(ctx, cipherString.data())) {
       
   284         // ### Bad error code
       
   285         q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg(SSL_ERRORSTR()));
       
   286         q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   287         emit q->error(QAbstractSocket::UnknownSocketError);
       
   288         return false;
       
   289     }
       
   290 
       
   291     // Add all our CAs to this store.
       
   292     foreach (const QSslCertificate &caCertificate, q->caCertificates())
       
   293         q_X509_STORE_add_cert(ctx->cert_store, (X509 *)caCertificate.handle());
       
   294 
       
   295     // Register a custom callback to get all verification errors.
       
   296     X509_STORE_set_verify_cb_func(ctx->cert_store, q_X509Callback);
       
   297 
       
   298     if (!configuration.localCertificate.isNull()) {
       
   299         // Require a private key as well.
       
   300         if (configuration.privateKey.isNull()) {
       
   301             q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(SSL_ERRORSTR()));
       
   302             emit q->error(QAbstractSocket::UnknownSocketError);
       
   303             return false;
       
   304         }
       
   305 
       
   306         // Load certificate
       
   307         if (!q_SSL_CTX_use_certificate(ctx, (X509 *)configuration.localCertificate.handle())) {
       
   308             q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg(SSL_ERRORSTR()));
       
   309             emit q->error(QAbstractSocket::UnknownSocketError);
       
   310             return false;
       
   311         }
       
   312 
       
   313         // Load private key
       
   314         EVP_PKEY *pkey = q_EVP_PKEY_new();
       
   315         if (configuration.privateKey.algorithm() == QSsl::Rsa)
       
   316             q_EVP_PKEY_assign_RSA(pkey, (RSA *)configuration.privateKey.handle());
       
   317         else
       
   318             q_EVP_PKEY_assign_DSA(pkey, (DSA *)configuration.privateKey.handle());
       
   319         if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
       
   320             q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(SSL_ERRORSTR()));
       
   321             emit q->error(QAbstractSocket::UnknownSocketError);
       
   322             return false;
       
   323         }
       
   324 
       
   325         // Check if the certificate matches the private key.
       
   326         if (!q_SSL_CTX_check_private_key(ctx)) {
       
   327             q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(SSL_ERRORSTR()));
       
   328             emit q->error(QAbstractSocket::UnknownSocketError);
       
   329             return false;
       
   330         }
       
   331     }
       
   332 
       
   333     // Initialize peer verification.
       
   334     if (configuration.peerVerifyMode == QSslSocket::VerifyNone) {
       
   335         q_SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
       
   336     } else {
       
   337         q_SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, q_X509Callback);
       
   338     }
       
   339 
       
   340     // Set verification depth.
       
   341     if (configuration.peerVerifyDepth != 0)
       
   342         q_SSL_CTX_set_verify_depth(ctx, configuration.peerVerifyDepth);
       
   343     
       
   344     // Create and initialize SSL session
       
   345     if (!(ssl = q_SSL_new(ctx))) {
       
   346         // ### Bad error code
       
   347         q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg(SSL_ERRORSTR()));
       
   348         q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   349         emit q->error(QAbstractSocket::UnknownSocketError);
       
   350         return false;
       
   351     }
       
   352 
       
   353     // Clear the session.
       
   354     q_SSL_clear(ssl);
       
   355     errorList.clear();
       
   356 
       
   357     // Initialize memory BIOs for encryption and decryption.
       
   358     readBio = q_BIO_new(q_BIO_s_mem());
       
   359     writeBio = q_BIO_new(q_BIO_s_mem());
       
   360     if (!readBio || !writeBio) {
       
   361         // ### Bad error code
       
   362         q->setErrorString(QSslSocket::tr("Error creating SSL session: %1").arg(SSL_ERRORSTR()));
       
   363         q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   364         emit q->error(QAbstractSocket::UnknownSocketError);
       
   365         return false;
       
   366     }
       
   367 
       
   368     // Assign the bios.
       
   369     q_SSL_set_bio(ssl, readBio, writeBio);
       
   370 
       
   371     if (mode == QSslSocket::SslClientMode)
       
   372         q_SSL_set_connect_state(ssl);
       
   373     else
       
   374         q_SSL_set_accept_state(ssl);
       
   375 
       
   376     return true;
       
   377 }
       
   378 
       
   379 /*!
       
   380     \internal
       
   381 */
       
   382 void QSslSocketPrivate::deinitialize()
       
   383 {
       
   384     q_CRYPTO_set_id_callback(0);
       
   385     q_CRYPTO_set_locking_callback(0);
       
   386 }
       
   387 
       
   388 /*!
       
   389     \internal
       
   390 
       
   391     Declared static in QSslSocketPrivate, makes sure the SSL libraries have
       
   392     been initialized.
       
   393 */
       
   394 bool QSslSocketPrivate::ensureInitialized()
       
   395 {
       
   396     if (!q_resolveOpenSslSymbols())
       
   397         return false;
       
   398 
       
   399     // Check if the library itself needs to be initialized.
       
   400     QMutexLocker locker(openssl_locks()->initLock());
       
   401     static int q_initialized = false;
       
   402     if (!q_initialized) {
       
   403         q_initialized = true;
       
   404 
       
   405         // Initialize resources
       
   406         initNetworkResources();
       
   407 
       
   408         // Initialize OpenSSL.
       
   409         q_CRYPTO_set_id_callback(id_function);
       
   410         q_CRYPTO_set_locking_callback(locking_function);
       
   411         if (q_SSL_library_init() != 1)
       
   412             return false;
       
   413         q_SSL_load_error_strings();
       
   414         q_OpenSSL_add_all_algorithms();
       
   415 
       
   416         // Initialize OpenSSL's random seed.
       
   417         if (!q_RAND_status()) {
       
   418             struct {
       
   419                 int msec;
       
   420                 int sec;
       
   421                 void *stack;
       
   422             } randomish;
       
   423 
       
   424             int attempts = 500;
       
   425             do {
       
   426                 if (attempts < 500) {
       
   427 #ifdef Q_OS_UNIX
       
   428                     struct timespec ts = {0, 33333333};
       
   429                     nanosleep(&ts, 0);
       
   430 #else
       
   431                     Sleep(3);
       
   432 #endif
       
   433                     randomish.msec = attempts;
       
   434                 }
       
   435                 randomish.stack = (void *)&randomish;
       
   436                 randomish.msec = QTime::currentTime().msec();
       
   437                 randomish.sec = QTime::currentTime().second();
       
   438                 q_RAND_seed((const char *)&randomish, sizeof(randomish));
       
   439             } while (!q_RAND_status() && --attempts);
       
   440             if (!attempts)
       
   441                 return false;
       
   442         }
       
   443 
       
   444         resetDefaultCiphers();
       
   445         setDefaultCaCertificates(systemCaCertificates());
       
   446     }
       
   447     return true;
       
   448 }
       
   449 
       
   450 /*!
       
   451     \internal
       
   452 
       
   453     Declared static in QSslSocketPrivate, backend-dependent loading of
       
   454     application-wide global ciphers.
       
   455 */
       
   456 void QSslSocketPrivate::resetDefaultCiphers()
       
   457 {
       
   458     SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());
       
   459     SSL *mySsl = q_SSL_new(myCtx);
       
   460 
       
   461     QList<QSslCipher> ciphers;
       
   462 
       
   463     STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(mySsl);
       
   464     for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
       
   465         if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
       
   466             if (cipher->valid) {
       
   467                 QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
       
   468                 if (!ciph.isNull()) {
       
   469                     if (!ciph.name().toLower().startsWith(QLatin1String("adh")))
       
   470                         ciphers << ciph;
       
   471                 }
       
   472             }
       
   473         }
       
   474     }
       
   475 
       
   476     q_SSL_CTX_free(myCtx);
       
   477     q_SSL_free(mySsl);
       
   478 
       
   479     setDefaultSupportedCiphers(ciphers);
       
   480     setDefaultCiphers(ciphers);
       
   481 }
       
   482 
       
   483 QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
       
   484 {
       
   485     // Qt provides a default bundle of certificates
       
   486     QFile caBundle(QLatin1String(":/trolltech/network/ssl/qt-ca-bundle.crt"));
       
   487     if (caBundle.open(QIODevice::ReadOnly | QIODevice::Text))
       
   488         return QSslCertificate::fromDevice(&caBundle);
       
   489 
       
   490     // Unreachable; return no bundle.
       
   491     return QList<QSslCertificate>();
       
   492 }
       
   493 
       
   494 void QSslSocketBackendPrivate::startClientEncryption()
       
   495 {
       
   496     if (!initSslContext()) {
       
   497         // ### report error: internal OpenSSL failure
       
   498         return;
       
   499     }
       
   500 
       
   501     // Start connecting. This will place outgoing data in the BIO, so we
       
   502     // follow up with calling transmit().
       
   503     startHandshake();
       
   504     transmit();
       
   505 }
       
   506 
       
   507 void QSslSocketBackendPrivate::startServerEncryption()
       
   508 {
       
   509     if (!initSslContext()) {
       
   510         // ### report error: internal OpenSSL failure
       
   511         return;
       
   512     }
       
   513 
       
   514     // Start connecting. This will place outgoing data in the BIO, so we
       
   515     // follow up with calling transmit().
       
   516     startHandshake();
       
   517     transmit();
       
   518 }
       
   519 
       
   520 /*!
       
   521     \internal
       
   522 
       
   523     Transmits encrypted data between the BIOs and the socket.
       
   524 */
       
   525 void QSslSocketBackendPrivate::transmit()
       
   526 {
       
   527     Q_Q(QSslSocket);
       
   528 
       
   529     // If we don't have any SSL context, don't bother transmitting.
       
   530     if (!ssl)
       
   531         return;
       
   532 
       
   533     bool transmitting;
       
   534     do {
       
   535         transmitting = false;
       
   536         
       
   537         // If the connection is secure, we can transfer data from the write
       
   538         // buffer (in plain text) to the write BIO through SSL_write.
       
   539         if (connectionEncrypted && !writeBuffer.isEmpty()) {
       
   540             qint64 totalBytesWritten = 0;
       
   541             int nextDataBlockSize;
       
   542             while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
       
   543                 int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize);
       
   544                 if (writtenBytes <= 0) {
       
   545                     // ### Better error handling.
       
   546                     q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(SSL_ERRORSTR()));
       
   547                     q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   548                     emit q->error(QAbstractSocket::UnknownSocketError);
       
   549                     return;
       
   550                 }
       
   551 #ifdef QSSLSOCKET_DEBUG
       
   552                 qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes";
       
   553 #endif
       
   554                 writeBuffer.free(writtenBytes);
       
   555                 totalBytesWritten += writtenBytes;
       
   556 
       
   557                 if (writtenBytes < nextDataBlockSize) {
       
   558                     // break out of the writing loop and try again after we had read
       
   559                     transmitting = true;
       
   560                     break;
       
   561                 }
       
   562             }
       
   563 
       
   564             if (totalBytesWritten > 0) {
       
   565                 // Don't emit bytesWritten() recursively.
       
   566                 if (!emittedBytesWritten) {
       
   567                     emittedBytesWritten = true;
       
   568                     emit q->bytesWritten(totalBytesWritten);
       
   569                     emittedBytesWritten = false;
       
   570                 }
       
   571             }
       
   572         }
       
   573 
       
   574         // Check if we've got any data to be written to the socket.
       
   575         QVarLengthArray<char, 4096> data;
       
   576         int pendingBytes;
       
   577         while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0) {
       
   578             // Read encrypted data from the write BIO into a buffer.
       
   579             data.resize(pendingBytes);
       
   580             int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
       
   581 
       
   582             // Write encrypted data from the buffer to the socket.
       
   583             plainSocket->write(data.constData(), encryptedBytesRead);
       
   584 #ifdef QSSLSOCKET_DEBUG
       
   585             qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket";
       
   586 #endif
       
   587             transmitting = true;
       
   588         }
       
   589 
       
   590         // Check if we've got any data to be read from the socket.
       
   591         if (!connectionEncrypted || !readBufferMaxSize || readBuffer.size() < readBufferMaxSize)
       
   592             while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
       
   593                 // Read encrypted data from the socket into a buffer.
       
   594                 data.resize(pendingBytes);
       
   595                 // just peek() here because q_BIO_write could write less data than expected
       
   596                 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
       
   597 #ifdef QSSLSOCKET_DEBUG
       
   598                 qDebug() << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
       
   599 #endif
       
   600                 // Write encrypted data from the buffer into the read BIO.
       
   601                 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
       
   602 
       
   603                 // do the actual read() here and throw away the results.
       
   604                 if (writtenToBio > 0) {
       
   605                     // ### TODO: make this cheaper by not making it memcpy. E.g. make it work with data=0x0 or make it work with seek
       
   606                     plainSocket->read(data.data(), writtenToBio);
       
   607                 } else {
       
   608                     // ### Better error handling.
       
   609                     q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(SSL_ERRORSTR()));
       
   610                     q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   611                     emit q->error(QAbstractSocket::UnknownSocketError);
       
   612                     return;
       
   613                 }
       
   614 
       
   615                 transmitting = true;
       
   616             }
       
   617 
       
   618         // If the connection isn't secured yet, this is the time to retry the
       
   619         // connect / accept.
       
   620         if (!connectionEncrypted) {
       
   621 #ifdef QSSLSOCKET_DEBUG
       
   622             qDebug() << "QSslSocketBackendPrivate::transmit: testing encryption";
       
   623 #endif
       
   624             if (startHandshake()) {
       
   625 #ifdef QSSLSOCKET_DEBUG
       
   626                 qDebug() << "QSslSocketBackendPrivate::transmit: encryption established";
       
   627 #endif
       
   628                 connectionEncrypted = true;
       
   629                 transmitting = true;
       
   630             } else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
       
   631 #ifdef QSSLSOCKET_DEBUG
       
   632                 qDebug() << "QSslSocketBackendPrivate::transmit: connection lost";
       
   633 #endif
       
   634                 break;
       
   635             } else {
       
   636 #ifdef QSSLSOCKET_DEBUG
       
   637                 qDebug() << "QSslSocketBackendPrivate::transmit: encryption not done yet";
       
   638 #endif
       
   639             }
       
   640         }
       
   641 
       
   642         // If the request is small and the remote host closes the transmission
       
   643         // after sending, there's a chance that startHandshake() will already
       
   644         // have triggered a shutdown.
       
   645         if (!ssl)
       
   646             continue;
       
   647 
       
   648         // We always read everything from the SSL decryption buffers, even if
       
   649         // we have a readBufferMaxSize. There's no point in leaving data there
       
   650         // just so that readBuffer.size() == readBufferMaxSize.
       
   651         int readBytes = 0;
       
   652         data.resize(4096);
       
   653         ::memset(data.data(), 0, data.size());
       
   654         do {
       
   655             // Don't use SSL_pending(). It's very unreliable.
       
   656             if ((readBytes = q_SSL_read(ssl, data.data(), data.size())) > 0) {
       
   657 #ifdef QSSLSOCKET_DEBUG
       
   658                 qDebug() << "QSslSocketBackendPrivate::transmit: decrypted" << readBytes << "bytes";
       
   659 #endif
       
   660                 char *ptr = readBuffer.reserve(readBytes);
       
   661                 ::memcpy(ptr, data.data(), readBytes);
       
   662 
       
   663                 if (readyReadEmittedPointer)
       
   664                     *readyReadEmittedPointer = true;
       
   665                 emit q->readyRead();
       
   666                 transmitting = true;
       
   667                 continue;
       
   668             }
       
   669 
       
   670             // Error.
       
   671             switch (q_SSL_get_error(ssl, readBytes)) {
       
   672             case SSL_ERROR_WANT_READ:
       
   673             case SSL_ERROR_WANT_WRITE:
       
   674                 // Out of data.
       
   675                 break;
       
   676             case SSL_ERROR_ZERO_RETURN:
       
   677                 // The remote host closed the connection.
       
   678 #ifdef QSSLSOCKET_DEBUG
       
   679                 qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect";
       
   680 #endif
       
   681                 plainSocket->disconnectFromHost();
       
   682                 break;
       
   683             default:
       
   684                 // ### Handle errors better.
       
   685                 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(SSL_ERRORSTR()));
       
   686                 q->setSocketError(QAbstractSocket::UnknownSocketError);
       
   687                 emit q->error(QAbstractSocket::UnknownSocketError);
       
   688                 break;
       
   689             }
       
   690         } while (ssl && readBytes > 0);
       
   691     } while (ssl && ctx && transmitting);
       
   692 }
       
   693 
       
   694 static QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert)
       
   695 {
       
   696     QSslError error;
       
   697     switch (errorCode) {
       
   698     case X509_V_OK:
       
   699         // X509_V_OK is also reported if the peer had no certificate.
       
   700         break;
       
   701     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
       
   702         error = QSslError(QSslError::UnableToGetIssuerCertificate, cert); break;
       
   703     case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
       
   704         error = QSslError(QSslError::UnableToDecryptCertificateSignature, cert); break;
       
   705     case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
       
   706         error = QSslError(QSslError::UnableToDecodeIssuerPublicKey, cert); break;
       
   707     case X509_V_ERR_CERT_SIGNATURE_FAILURE:
       
   708         error = QSslError(QSslError::CertificateSignatureFailed, cert); break;
       
   709     case X509_V_ERR_CERT_NOT_YET_VALID:
       
   710         error = QSslError(QSslError::CertificateNotYetValid, cert); break;
       
   711     case X509_V_ERR_CERT_HAS_EXPIRED:
       
   712         error = QSslError(QSslError::CertificateExpired, cert); break;
       
   713     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
       
   714         error = QSslError(QSslError::InvalidNotBeforeField, cert); break;
       
   715     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
       
   716         error = QSslError(QSslError::InvalidNotAfterField, cert); break;
       
   717     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
       
   718         error = QSslError(QSslError::SelfSignedCertificate, cert); break;
       
   719     case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
       
   720         error = QSslError(QSslError::SelfSignedCertificateInChain, cert); break;
       
   721     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
       
   722         error = QSslError(QSslError::UnableToGetLocalIssuerCertificate, cert); break;
       
   723     case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
       
   724         error = QSslError(QSslError::UnableToVerifyFirstCertificate, cert); break;
       
   725     case X509_V_ERR_CERT_REVOKED:
       
   726         error = QSslError(QSslError::CertificateRevoked, cert); break;
       
   727     case X509_V_ERR_INVALID_CA:
       
   728         error = QSslError(QSslError::InvalidCaCertificate, cert); break;
       
   729     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
       
   730         error = QSslError(QSslError::PathLengthExceeded, cert); break;
       
   731     case X509_V_ERR_INVALID_PURPOSE:
       
   732         error = QSslError(QSslError::InvalidPurpose, cert); break;
       
   733     case X509_V_ERR_CERT_UNTRUSTED:
       
   734         error = QSslError(QSslError::CertificateUntrusted, cert); break;
       
   735     case X509_V_ERR_CERT_REJECTED:
       
   736         error = QSslError(QSslError::CertificateRejected, cert); break;
       
   737     default:
       
   738         error = QSslError(QSslError::UnspecifiedError, cert); break;
       
   739     }
       
   740     return error;
       
   741 }
       
   742 
       
   743 bool QSslSocketBackendPrivate::startHandshake()
       
   744 {
       
   745     Q_Q(QSslSocket);
       
   746 
       
   747     // Check if the connection has been established. Get all errors from the
       
   748     // verification stage.
       
   749     _q_sslErrorList()->mutex.lock();
       
   750     _q_sslErrorList()->errors.clear();
       
   751     int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
       
   752 
       
   753     const QList<QPair<int, int> > &lastErrors = _q_sslErrorList()->errors;
       
   754     for (int i = 0; i < lastErrors.size(); ++i) {
       
   755         const QPair<int, int> &currentError = lastErrors.at(i);
       
   756         // Initialize the peer certificate chain in order to find which certificate caused this error
       
   757         if (configuration.peerCertificateChain.isEmpty())
       
   758             configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
       
   759         emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.first,
       
   760                                 configuration.peerCertificateChain.value(currentError.second)));
       
   761         if (q->state() != QAbstractSocket::ConnectedState)
       
   762             break;
       
   763     }
       
   764 
       
   765     errorList << lastErrors;
       
   766     _q_sslErrorList()->mutex.unlock();
       
   767 
       
   768     // Connection aborted during handshake phase.
       
   769     if (q->state() != QAbstractSocket::ConnectedState)
       
   770         return false;
       
   771 
       
   772     // Check if we're encrypted or not.
       
   773     if (result <= 0) {
       
   774         switch (q_SSL_get_error(ssl, result)) {
       
   775         case SSL_ERROR_WANT_READ:
       
   776         case SSL_ERROR_WANT_WRITE:
       
   777             // The handshake is not yet complete.
       
   778             break;
       
   779         default:
       
   780             // ### Handle errors better
       
   781             q->setErrorString(QSslSocket::tr("Error during SSL handshake: %1").arg(SSL_ERRORSTR()));
       
   782             q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
       
   783 #ifdef QSSLSOCKET_DEBUG
       
   784             qDebug() << "QSslSocketBackendPrivate::startHandshake: error!" << q->errorString();
       
   785 #endif
       
   786             emit q->error(QAbstractSocket::SslHandshakeFailedError);
       
   787             q->abort();
       
   788         }
       
   789         return false;
       
   790     }
       
   791 
       
   792     // Store the peer certificate and chain. For clients, the peer certificate
       
   793     // chain includes the peer certificate; for servers, it doesn't. Both the
       
   794     // peer certificate and the chain may be empty if the peer didn't present
       
   795     // any certificate.
       
   796     if (configuration.peerCertificateChain.isEmpty())
       
   797         configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
       
   798     X509 *x509 = q_SSL_get_peer_certificate(ssl);
       
   799     configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
       
   800     q_X509_free(x509);
       
   801 
       
   802     // Start translating errors.
       
   803     QList<QSslError> errors;
       
   804     bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
       
   805                         || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
       
   806                             && mode == QSslSocket::SslClientMode);
       
   807 
       
   808     // Check the peer certificate itself. First try the subject's common name
       
   809     // (CN) as a wildcard, then try all alternate subject name DNS entries the
       
   810     // same way.
       
   811     if (!configuration.peerCertificate.isNull()) {
       
   812         // but only if we're a client connecting to a server
       
   813         // if we're the server, don't check CN
       
   814         if (mode == QSslSocket::SslClientMode) {
       
   815             QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
       
   816             QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
       
   817 
       
   818             QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard);
       
   819             if (!regexp.exactMatch(peerName)) {
       
   820                 bool matched = false;
       
   821                 foreach (const QString &altName, configuration.peerCertificate
       
   822                          .alternateSubjectNames().values(QSsl::DnsEntry)) {
       
   823                     regexp.setPattern(altName);
       
   824                     if (regexp.exactMatch(peerName)) {
       
   825                         matched = true;
       
   826                         break;
       
   827                     }
       
   828                 }
       
   829                 if (!matched) {
       
   830                     // No matches in common names or alternate names.
       
   831                     QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
       
   832                     errors << error;
       
   833                     emit q->peerVerifyError(error);
       
   834                     if (q->state() != QAbstractSocket::ConnectedState)
       
   835                         return false;
       
   836                 }
       
   837             }
       
   838         }
       
   839     } else {
       
   840         // No peer certificate presented. Report as error if the socket
       
   841         // expected one.
       
   842         if (doVerifyPeer) {
       
   843             QSslError error(QSslError::NoPeerCertificate);
       
   844             errors << error;
       
   845             emit q->peerVerifyError(error);
       
   846             if (q->state() != QAbstractSocket::ConnectedState)
       
   847                 return false;
       
   848         }
       
   849     }
       
   850 
       
   851     // Translate errors from the error list into QSslErrors.
       
   852     for (int i = 0; i < errorList.size(); ++i) {
       
   853         const QPair<int, int> &errorAndDepth = errorList.at(i);
       
   854         int err = errorAndDepth.first;
       
   855         int depth = errorAndDepth.second;
       
   856         errors << _q_OpenSSL_to_QSslError(err, configuration.peerCertificateChain.value(depth));
       
   857     }
       
   858 
       
   859     if (!errors.isEmpty()) {
       
   860         sslErrors = errors;
       
   861         emit q->sslErrors(errors);
       
   862 
       
   863         bool doEmitSslError;
       
   864         if (!ignoreErrorsList.empty()) {
       
   865             // check whether the errors we got are all in the list of expected errors
       
   866             // (applies only if the method QSslSocket::ignoreSslErrors(const QList<QSslError> &errors)
       
   867             // was called)
       
   868             doEmitSslError = false;
       
   869             for (int a = 0; a < errors.count(); a++) {
       
   870                 if (!ignoreErrorsList.contains(errors.at(a))) {
       
   871                     doEmitSslError = true;
       
   872                     break;
       
   873                 }
       
   874             }
       
   875         } else {
       
   876             // if QSslSocket::ignoreSslErrors(const QList<QSslError> &errors) was not called and
       
   877             // we get an SSL error, emit a signal unless we ignored all errors (by calling
       
   878             // QSslSocket::ignoreSslErrors() )
       
   879             doEmitSslError = !ignoreAllSslErrors;
       
   880         }
       
   881         // check whether we need to emit an SSL handshake error
       
   882         if (doVerifyPeer && doEmitSslError) {
       
   883             q->setErrorString(sslErrors.first().errorString());
       
   884             q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
       
   885             emit q->error(QAbstractSocket::SslHandshakeFailedError);
       
   886             plainSocket->disconnectFromHost();
       
   887             return false;
       
   888         }
       
   889     } else {
       
   890         sslErrors.clear();
       
   891     }
       
   892 
       
   893     // if we have a max read buffer size, reset the plain socket's to 1k
       
   894     if (readBufferMaxSize)
       
   895         plainSocket->setReadBufferSize(1024);
       
   896 
       
   897     connectionEncrypted = true;
       
   898     emit q->encrypted();
       
   899     if (autoStartHandshake && pendingClose) {
       
   900         pendingClose = false;
       
   901         q->disconnectFromHost();
       
   902     }
       
   903     return true;
       
   904 }
       
   905 
       
   906 void QSslSocketBackendPrivate::disconnectFromHost()
       
   907 {
       
   908     if (ssl) {
       
   909         q_SSL_shutdown(ssl);
       
   910         transmit();
       
   911     }
       
   912     plainSocket->disconnectFromHost();
       
   913 }
       
   914 
       
   915 void QSslSocketBackendPrivate::disconnected()
       
   916 {
       
   917     if (ssl) {
       
   918         q_SSL_free(ssl);
       
   919         ssl = 0;
       
   920     }
       
   921     if (ctx) {
       
   922         q_SSL_CTX_free(ctx);
       
   923         ctx = 0;
       
   924     }
       
   925 }
       
   926 
       
   927 QSslCipher QSslSocketBackendPrivate::sessionCipher() const
       
   928 {
       
   929     if (!ssl || !ctx)
       
   930         return QSslCipher();
       
   931 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
       
   932     // FIXME This is fairly evil, but needed to keep source level compatibility
       
   933     // with the OpenSSL 0.9.x implementation at maximum -- some other functions
       
   934     // don't take a const SSL_CIPHER* when they should
       
   935     SSL_CIPHER *sessionCipher = const_cast<SSL_CIPHER *>(q_SSL_get_current_cipher(ssl));
       
   936 #else
       
   937     SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
       
   938 #endif
       
   939     return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher();
       
   940 }
       
   941 
       
   942 QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509)
       
   943 {
       
   944     ensureInitialized();
       
   945     QList<QSslCertificate> certificates;
       
   946     for (int i = 0; i < q_sk_X509_num(x509); ++i) {
       
   947         if (X509 *entry = q_sk_X509_value(x509, i))
       
   948             certificates << QSslCertificatePrivate::QSslCertificate_from_X509(entry);
       
   949     }
       
   950     return certificates;
       
   951 }
       
   952 
       
   953 QT_END_NAMESPACE