Prevent data loss when an ssl socket is closed by remote
[profile/ivi/qtbase.git] / src / network / ssl / qsslsocket_openssl.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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/qelapsedtimer.h>
55 #include <QtCore/qfile.h>
56 #include <QtCore/qfileinfo.h>
57 #include <QtCore/qmutex.h>
58 #include <QtCore/qthread.h>
59 #include <QtCore/qurl.h>
60 #include <QtCore/qvarlengtharray.h>
61 #include <QLibrary> // for loading the security lib for the CA store
62
63 QT_BEGIN_NAMESPACE
64
65 #if defined(Q_OS_MAC)
66 #define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
67     PtrSecCertificateGetData QSslSocketPrivate::ptrSecCertificateGetData = 0;
68     PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
69     PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0;
70 #elif defined(Q_OS_WIN)
71     PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0;
72     PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
73     PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
74 #endif
75
76 bool QSslSocketPrivate::s_libraryLoaded = false;
77 bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
78 bool QSslSocketPrivate::s_loadRootCertsOnDemand = false;
79
80 /* \internal
81
82     From OpenSSL's thread(3) manual page:
83
84     OpenSSL can safely be used in multi-threaded applications provided that at
85     least two callback functions are set.
86
87     locking_function(int mode, int n, const char *file, int line) is needed to
88     perform locking on shared data structures.  (Note that OpenSSL uses a
89     number of global data structures that will be implicitly shared
90     when-whenever ever multiple threads use OpenSSL.)  Multi-threaded
91     applications will crash at random if it is not set.  ...
92     ...
93     id_function(void) is a function that returns a thread ID. It is not
94     needed on Windows nor on platforms where getpid() returns a different
95     ID for each thread (most notably Linux)
96 */
97 class QOpenSslLocks
98 {
99 public:
100     inline QOpenSslLocks()
101         : initLocker(QMutex::Recursive),
102           locksLocker(QMutex::Recursive)
103     {
104         QMutexLocker locker(&locksLocker);
105         int numLocks = q_CRYPTO_num_locks();
106         locks = new QMutex *[numLocks];
107         memset(locks, 0, numLocks * sizeof(QMutex *));
108     }
109     inline ~QOpenSslLocks()
110     {
111         QMutexLocker locker(&locksLocker);
112         for (int i = 0; i < q_CRYPTO_num_locks(); ++i)
113             delete locks[i];
114         delete [] locks;
115
116         QSslSocketPrivate::deinitialize();
117     }
118     inline QMutex *lock(int num)
119     {
120         QMutexLocker locker(&locksLocker);
121         QMutex *tmp = locks[num];
122         if (!tmp)
123             tmp = locks[num] = new QMutex(QMutex::Recursive);
124         return tmp;
125     }
126
127     QMutex *globalLock()
128     {
129         return &locksLocker;
130     }
131
132     QMutex *initLock()
133     {
134         return &initLocker;
135     }
136
137 private:
138     QMutex initLocker;
139     QMutex locksLocker;
140     QMutex **locks;
141 };
142 Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks)
143
144 extern "C" {
145 static void locking_function(int mode, int lockNumber, const char *, int)
146 {
147     QMutex *mutex = openssl_locks()->lock(lockNumber);
148
149     // Lock or unlock it
150     if (mode & CRYPTO_LOCK)
151         mutex->lock();
152     else
153         mutex->unlock();
154 }
155 static unsigned long id_function()
156 {
157     return (quintptr)QThread::currentThreadId();
158 }
159 } // extern "C"
160
161 QSslSocketBackendPrivate::QSslSocketBackendPrivate()
162     : ssl(0),
163       ctx(0),
164       pkey(0),
165       readBio(0),
166       writeBio(0),
167       session(0)
168 {
169     // Calls SSL_library_init().
170     ensureInitialized();
171 }
172
173 QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
174 {
175     destroySslContext();
176 }
177
178 QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher)
179 {
180     QSslCipher ciph;
181
182     char buf [256];
183     QString descriptionOneLine = QString::fromLatin1(q_SSL_CIPHER_description(cipher, buf, sizeof(buf)));
184
185     QStringList descriptionList = descriptionOneLine.split(QLatin1String(" "), QString::SkipEmptyParts);
186     if (descriptionList.size() > 5) {
187         // ### crude code.
188         ciph.d->isNull = false;
189         ciph.d->name = descriptionList.at(0);
190
191         QString protoString = descriptionList.at(1);
192         ciph.d->protocolString = protoString;
193         ciph.d->protocol = QSsl::UnknownProtocol;
194         if (protoString == QLatin1String("SSLv3"))
195             ciph.d->protocol = QSsl::SslV3;
196         else if (protoString == QLatin1String("SSLv2"))
197             ciph.d->protocol = QSsl::SslV2;
198         else if (protoString == QLatin1String("TLSv1"))
199             ciph.d->protocol = QSsl::TlsV1_0;
200
201         if (descriptionList.at(2).startsWith(QLatin1String("Kx=")))
202             ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3);
203         if (descriptionList.at(3).startsWith(QLatin1String("Au=")))
204             ciph.d->authenticationMethod = descriptionList.at(3).mid(3);
205         if (descriptionList.at(4).startsWith(QLatin1String("Enc=")))
206             ciph.d->encryptionMethod = descriptionList.at(4).mid(4);
207         ciph.d->exportable = (descriptionList.size() > 6 && descriptionList.at(6) == QLatin1String("export"));
208
209         ciph.d->bits = cipher->strength_bits;
210         ciph.d->supportedBits = cipher->alg_bits;
211
212     }
213     return ciph;
214 }
215
216 // ### This list is shared between all threads, and protected by a
217 // mutex. Investigate using thread local storage instead.
218 struct QSslErrorList
219 {
220     QMutex mutex;
221     QList<QPair<int, int> > errors;
222 };
223 Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
224 static int q_X509Callback(int ok, X509_STORE_CTX *ctx)
225 {
226     if (!ok) {
227         // Store the error and at which depth the error was detected.
228         _q_sslErrorList()->errors << qMakePair<int, int>(ctx->error, ctx->error_depth);
229 #ifdef QSSLSOCKET_DEBUG
230         qDebug() << "verification error: dumping bad certificate";
231         qDebug() << QSslCertificatePrivate::QSslCertificate_from_X509(ctx->current_cert).toPem();
232         qDebug() << "dumping chain";
233         foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ctx->chain)) {
234             QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6"));
235             qDebug() << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
236                 << "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
237                 << "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
238                 << "OU=" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName)
239                 << "C=" << cert.issuerInfo(QSslCertificate::CountryName)
240                 << "ST=" << cert.issuerInfo(QSslCertificate::StateOrProvinceName);
241             qDebug() << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization)
242                 << "CN=" << cert.subjectInfo(QSslCertificate::CommonName)
243                 << "L=" << cert.subjectInfo(QSslCertificate::LocalityName)
244                 << "OU=" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName)
245                 << "C=" << cert.subjectInfo(QSslCertificate::CountryName)
246                 << "ST=" << cert.subjectInfo(QSslCertificate::StateOrProvinceName);
247             qDebug() << "Valid:" << cert.effectiveDate() << "-" << cert.expiryDate();
248         }
249 #endif
250     }
251     // Always return OK to allow verification to continue. We're handle the
252     // errors gracefully after collecting all errors, after verification has
253     // completed.
254     return 1;
255 }
256
257 long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions)
258 {
259     long options;
260     if (protocol == QSsl::TlsV1SslV3 || protocol == QSsl::SecureProtocols)
261         options = SSL_OP_ALL|SSL_OP_NO_SSLv2;
262     else
263         options = SSL_OP_ALL;
264
265     // This option is disabled by default, so we need to be able to clear it
266     if (sslOptions & QSsl::SslOptionDisableEmptyFragments)
267         options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
268     else
269         options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
270
271 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
272     // This option is disabled by default, so we need to be able to clear it
273     if (sslOptions & QSsl::SslOptionDisableLegacyRenegotiation)
274         options &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
275     else
276         options |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
277 #endif
278
279 #ifdef SSL_OP_NO_TICKET
280     if (sslOptions & QSsl::SslOptionDisableSessionTickets)
281         options |= SSL_OP_NO_TICKET;
282 #endif
283 #ifdef SSL_OP_NO_COMPRESSION
284     if (sslOptions & QSsl::SslOptionDisableCompression)
285         options |= SSL_OP_NO_COMPRESSION;
286 #endif
287
288     return options;
289 }
290
291 bool QSslSocketBackendPrivate::initSslContext()
292 {
293     Q_Q(QSslSocket);
294
295     // Create and initialize SSL context. Accept SSLv2, SSLv3 and TLSv1_0.
296     bool client = (mode == QSslSocket::SslClientMode);
297
298     bool reinitialized = false;
299
300 init_context:
301     switch (configuration.protocol) {
302     case QSsl::SslV2:
303 #ifndef OPENSSL_NO_SSL2
304         ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method());
305 #else
306         ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error
307 #endif
308         break;
309     case QSsl::SslV3:
310         ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method());
311         break;
312     case QSsl::SecureProtocols: // SslV2 will be disabled below
313     case QSsl::TlsV1SslV3: // SslV2 will be disabled below
314     case QSsl::AnyProtocol:
315     default:
316         ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
317         break;
318     case QSsl::TlsV1_0:
319         ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
320         break;
321     }
322     if (!ctx) {
323         // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
324         // by re-initializing the library.
325         if (!reinitialized) {
326             reinitialized = true;
327             if (q_SSL_library_init() == 1)
328                 goto init_context;
329         }
330
331         q->setErrorString(QSslSocket::tr("Error creating SSL context (%1)").arg(getErrorsFromOpenSsl()));
332         q->setSocketError(QAbstractSocket::SslInternalError);
333         emit q->error(QAbstractSocket::SslInternalError);
334         return false;
335     }
336
337     // Enable bug workarounds.
338     long options = setupOpenSslOptions(configuration.protocol, configuration.sslOptions);
339     q_SSL_CTX_set_options(ctx, options);
340
341     // Initialize ciphers
342     QByteArray cipherString;
343     int first = true;
344     QList<QSslCipher> ciphers = configuration.ciphers;
345     if (ciphers.isEmpty())
346         ciphers = defaultCiphers();
347     foreach (const QSslCipher &cipher, ciphers) {
348         if (first)
349             first = false;
350         else
351             cipherString.append(':');
352         cipherString.append(cipher.name().toLatin1());
353     }
354
355     if (!q_SSL_CTX_set_cipher_list(ctx, cipherString.data())) {
356         q->setErrorString(QSslSocket::tr("Invalid or empty cipher list (%1)").arg(getErrorsFromOpenSsl()));
357         q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
358         emit q->error(QAbstractSocket::SslInvalidUserDataError);
359         return false;
360     }
361
362     // Add all our CAs to this store.
363     QList<QSslCertificate> expiredCerts;
364     foreach (const QSslCertificate &caCertificate, q->caCertificates()) {
365         // add expired certs later, so that the
366         // valid ones are used before the expired ones
367         if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
368             expiredCerts.append(caCertificate);
369         } else {
370             q_X509_STORE_add_cert(ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
371         }
372     }
373
374     bool addExpiredCerts = true;
375 #if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
376     //On Leopard SSL does not work if we add the expired certificates.
377     if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
378        addExpiredCerts = false;
379 #endif
380     // now add the expired certs
381     if (addExpiredCerts) {
382         foreach (const QSslCertificate &caCertificate, expiredCerts) {
383             q_X509_STORE_add_cert(ctx->cert_store, reinterpret_cast<X509 *>(caCertificate.handle()));
384         }
385     }
386
387     if (s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) {
388         // tell OpenSSL the directories where to look up the root certs on demand
389         QList<QByteArray> unixDirs = unixRootCertDirectories();
390         for (int a = 0; a < unixDirs.count(); ++a)
391             q_SSL_CTX_load_verify_locations(ctx, 0, unixDirs.at(a).constData());
392     }
393
394     // Register a custom callback to get all verification errors.
395     X509_STORE_set_verify_cb_func(ctx->cert_store, q_X509Callback);
396
397     if (!configuration.localCertificate.isNull()) {
398         // Require a private key as well.
399         if (configuration.privateKey.isNull()) {
400             q->setErrorString(QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(getErrorsFromOpenSsl()));
401             q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
402             emit q->error(QAbstractSocket::SslInvalidUserDataError);
403             return false;
404         }
405
406         // Load certificate
407         if (!q_SSL_CTX_use_certificate(ctx, reinterpret_cast<X509 *>(configuration.localCertificate.handle()))) {
408             q->setErrorString(QSslSocket::tr("Error loading local certificate, %1").arg(getErrorsFromOpenSsl()));
409             q->setSocketError(QAbstractSocket::SslInternalError);
410             emit q->error(QAbstractSocket::SslInternalError);
411             return false;
412         }
413
414         if (configuration.privateKey.algorithm() == QSsl::Opaque) {
415             pkey = reinterpret_cast<EVP_PKEY *>(configuration.privateKey.handle());
416         } else {
417             // Load private key
418             pkey = q_EVP_PKEY_new();
419             // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free.
420             // this lead to a memory leak. Now we use the *_set1_* functions which do not
421             // take ownership of the RSA/DSA key instance because the QSslKey already has ownership.
422             if (configuration.privateKey.algorithm() == QSsl::Rsa)
423                 q_EVP_PKEY_set1_RSA(pkey, reinterpret_cast<RSA *>(configuration.privateKey.handle()));
424             else
425                 q_EVP_PKEY_set1_DSA(pkey, reinterpret_cast<DSA *>(configuration.privateKey.handle()));
426         }
427
428         if (!q_SSL_CTX_use_PrivateKey(ctx, pkey)) {
429             q->setErrorString(QSslSocket::tr("Error loading private key, %1").arg(getErrorsFromOpenSsl()));
430             q->setSocketError(QAbstractSocket::SslInternalError);
431             emit q->error(QAbstractSocket::SslInternalError);
432             return false;
433         }
434         if (configuration.privateKey.algorithm() == QSsl::Opaque)
435             pkey = 0; // Don't free the private key, it belongs to QSslKey
436
437         // Check if the certificate matches the private key.
438         if (!q_SSL_CTX_check_private_key(ctx)) {
439             q->setErrorString(QSslSocket::tr("Private key does not certify public key, %1").arg(getErrorsFromOpenSsl()));
440             q->setSocketError(QAbstractSocket::SslInvalidUserDataError);
441             emit q->error(QAbstractSocket::SslInvalidUserDataError);
442             return false;
443         }
444     }
445
446     // Initialize peer verification.
447     if (configuration.peerVerifyMode == QSslSocket::VerifyNone) {
448         q_SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
449     } else {
450         q_SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, q_X509Callback);
451     }
452
453     // Set verification depth.
454     if (configuration.peerVerifyDepth != 0)
455         q_SSL_CTX_set_verify_depth(ctx, configuration.peerVerifyDepth);
456
457     // Create and initialize SSL session
458     if (!(ssl = q_SSL_new(ctx))) {
459         // ### Bad error code
460         q->setErrorString(QSslSocket::tr("Error creating SSL session, %1").arg(getErrorsFromOpenSsl()));
461         q->setSocketError(QAbstractSocket::SslInternalError);
462         emit q->error(QAbstractSocket::SslInternalError);
463         return false;
464     }
465
466 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
467     if ((configuration.protocol == QSsl::TlsV1SslV3 ||
468         configuration.protocol == QSsl::TlsV1_0 ||
469         configuration.protocol == QSsl::SecureProtocols ||
470         configuration.protocol == QSsl::AnyProtocol) &&
471         client && q_SSLeay() >= 0x00090806fL) {
472         // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format.
473         QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
474         if (tlsHostName.isEmpty())
475             tlsHostName = hostName;
476         QByteArray ace = QUrl::toAce(tlsHostName);
477         // only send the SNI header if the URL is valid and not an IP
478         if (!ace.isEmpty()
479             && !QHostAddress().setAddress(tlsHostName)
480             && !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) {
481             if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
482                 qWarning("could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
483         }
484     }
485 #endif
486
487     // Clear the session.
488     q_SSL_clear(ssl);
489     errorList.clear();
490
491     // Initialize memory BIOs for encryption and decryption.
492     readBio = q_BIO_new(q_BIO_s_mem());
493     writeBio = q_BIO_new(q_BIO_s_mem());
494     if (!readBio || !writeBio) {
495         q->setErrorString(QSslSocket::tr("Error creating SSL session: %1").arg(getErrorsFromOpenSsl()));
496         q->setSocketError(QAbstractSocket::SslInternalError);
497         emit q->error(QAbstractSocket::SslInternalError);
498         return false;
499     }
500
501     // Assign the bios.
502     q_SSL_set_bio(ssl, readBio, writeBio);
503
504     if (mode == QSslSocket::SslClientMode)
505         q_SSL_set_connect_state(ssl);
506     else
507         q_SSL_set_accept_state(ssl);
508
509     return true;
510 }
511
512 void QSslSocketBackendPrivate::destroySslContext()
513 {
514     if (ssl) {
515         q_SSL_free(ssl);
516         ssl = 0;
517     }
518     if (ctx) {
519         q_SSL_CTX_free(ctx);
520         ctx = 0;
521     }
522     if (pkey) {
523         q_EVP_PKEY_free(pkey);
524         pkey = 0;
525     }
526 }
527
528 /*!
529     \internal
530 */
531 void QSslSocketPrivate::deinitialize()
532 {
533     q_CRYPTO_set_id_callback(0);
534     q_CRYPTO_set_locking_callback(0);
535 }
536
537 /*!
538     \internal
539
540     Does the minimum amount of initialization to determine whether SSL
541     is supported or not.
542 */
543
544 bool QSslSocketPrivate::supportsSsl()
545 {
546     return ensureLibraryLoaded();
547 }
548
549 bool QSslSocketPrivate::ensureLibraryLoaded()
550 {
551     if (!q_resolveOpenSslSymbols())
552         return false;
553
554     // Check if the library itself needs to be initialized.
555     QMutexLocker locker(openssl_locks()->initLock());
556     if (!s_libraryLoaded) {
557         s_libraryLoaded = true;
558
559         // Initialize OpenSSL.
560         q_CRYPTO_set_id_callback(id_function);
561         q_CRYPTO_set_locking_callback(locking_function);
562         if (q_SSL_library_init() != 1)
563             return false;
564         q_SSL_load_error_strings();
565         q_OpenSSL_add_all_algorithms();
566
567         // Initialize OpenSSL's random seed.
568         if (!q_RAND_status()) {
569             struct {
570                 int msec;
571                 int sec;
572                 void *stack;
573             } randomish;
574
575             int attempts = 500;
576             do {
577                 if (attempts < 500) {
578 #ifdef Q_OS_UNIX
579                     struct timespec ts = {0, 33333333};
580                     nanosleep(&ts, 0);
581 #else
582                     Sleep(3);
583 #endif
584                     randomish.msec = attempts;
585                 }
586                 randomish.stack = (void *)&randomish;
587                 randomish.msec = QTime::currentTime().msec();
588                 randomish.sec = QTime::currentTime().second();
589                 q_RAND_seed((const char *)&randomish, sizeof(randomish));
590             } while (!q_RAND_status() && --attempts);
591             if (!attempts)
592                 return false;
593         }
594     }
595     return true;
596 }
597
598 void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
599 {
600     QMutexLocker locker(openssl_locks()->initLock());
601     if (s_loadedCiphersAndCerts)
602         return;
603     s_loadedCiphersAndCerts = true;
604
605     resetDefaultCiphers();
606
607     //load symbols needed to receive certificates from system store
608 #if defined(Q_OS_MAC)
609     QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
610     if (securityLib.load()) {
611         ptrSecCertificateGetData = (PtrSecCertificateGetData) securityLib.resolve("SecCertificateGetData");
612         if (!ptrSecCertificateGetData)
613             qWarning("could not resolve symbols in security library"); // should never happen
614
615         ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates");
616         if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there
617             ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates");
618             if (!ptrSecTrustCopyAnchorCertificates)
619                 qWarning("could not resolve symbols in security library"); // should never happen
620         }
621     } else {
622         qWarning("could not load security library");
623     }
624 #elif defined(Q_OS_WIN)
625     HINSTANCE hLib = LoadLibraryW(L"Crypt32");
626     if (hLib) {
627 #if defined(Q_OS_WINCE)
628         ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, L"CertOpenStore");
629         ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, L"CertFindCertificateInStore");
630         ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, L"CertCloseStore");
631 #else
632         ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW");
633         ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore");
634         ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore");
635 #endif
636         if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore)
637             qWarning("could not resolve symbols in crypt32 library"); // should never happen
638     } else {
639         qWarning("could not load crypt32 library"); // should never happen
640     }
641 #elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
642     // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there)
643     QList<QByteArray> dirs = unixRootCertDirectories();
644     QStringList symLinkFilter;
645     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]");
646     for (int a = 0; a < dirs.count(); ++a) {
647         QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files);
648         if (iterator.hasNext()) {
649             s_loadRootCertsOnDemand = true;
650             break;
651         }
652     }
653 #endif
654     // if on-demand loading was not enabled, load the certs now
655     if (!s_loadRootCertsOnDemand)
656         setDefaultCaCertificates(systemCaCertificates());
657 }
658
659 /*!
660     \internal
661
662     Declared static in QSslSocketPrivate, makes sure the SSL libraries have
663     been initialized.
664 */
665
666 void QSslSocketPrivate::ensureInitialized()
667 {
668     if (!supportsSsl())
669         return;
670
671     ensureCiphersAndCertsLoaded();
672 }
673
674 long QSslSocketPrivate::sslLibraryVersionNumber()
675 {
676     return q_SSLeay();
677 }
678
679 QString QSslSocketPrivate::sslLibraryVersionString()
680 {
681     if (!supportsSsl())
682         return QString();
683
684     const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
685     if (!versionString)
686         return QString();
687
688     return QString::fromLatin1(versionString);
689 }
690
691 /*!
692     \internal
693
694     Declared static in QSslSocketPrivate, backend-dependent loading of
695     application-wide global ciphers.
696 */
697 void QSslSocketPrivate::resetDefaultCiphers()
698 {
699     SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method());
700     SSL *mySsl = q_SSL_new(myCtx);
701
702     QList<QSslCipher> ciphers;
703
704     STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(mySsl);
705     for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
706         if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) {
707             if (cipher->valid) {
708                 QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
709                 if (!ciph.isNull()) {
710                     if (!ciph.name().toLower().startsWith(QLatin1String("adh")))
711                         ciphers << ciph;
712                 }
713             }
714         }
715     }
716
717     q_SSL_CTX_free(myCtx);
718     q_SSL_free(mySsl);
719
720     setDefaultSupportedCiphers(ciphers);
721     setDefaultCiphers(ciphers);
722 }
723
724 QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
725 {
726     ensureInitialized();
727 #ifdef QSSLSOCKET_DEBUG
728     QElapsedTimer timer;
729     timer.start();
730 #endif
731     QList<QSslCertificate> systemCerts;
732 #if defined(Q_OS_MAC)
733     CFArrayRef cfCerts;
734     OSStatus status = 1;
735
736     OSStatus SecCertificateGetData (
737        SecCertificateRef certificate,
738        CSSM_DATA_PTR data
739     );
740
741     if (ptrSecCertificateGetData) {
742         if (ptrSecTrustSettingsCopyCertificates)
743             status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
744         else if (ptrSecTrustCopyAnchorCertificates)
745             status = ptrSecTrustCopyAnchorCertificates(&cfCerts);
746         if (!status) {
747             CFIndex size = CFArrayGetCount(cfCerts);
748             for (CFIndex i = 0; i < size; ++i) {
749                 SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
750                 CSSM_DATA data;
751                 CSSM_DATA_PTR dataPtr = &data;
752                 if (ptrSecCertificateGetData(cfCert, dataPtr)) {
753                     qWarning("error retrieving a CA certificate from the system store");
754                 } else {
755                     int len = data.Length;
756                     char *rawData = reinterpret_cast<char *>(data.Data);
757                     QByteArray rawCert(rawData, len);
758                     systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
759                 }
760             }
761             CFRelease(cfCerts);
762         }
763         else {
764            // no detailed error handling here
765            qWarning("could not retrieve system CA certificates");
766         }
767     }
768 #elif defined(Q_OS_WIN)
769     if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
770         HCERTSTORE hSystemStore;
771 #if defined(Q_OS_WINCE)
772         hSystemStore = ptrCertOpenSystemStoreW(CERT_STORE_PROV_SYSTEM_W,
773                                                0,
774                                                0,
775                                                CERT_STORE_NO_CRYPT_RELEASE_FLAG|CERT_SYSTEM_STORE_CURRENT_USER,
776                                                L"ROOT");
777 #else
778         hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT");
779 #endif
780         if(hSystemStore) {
781             PCCERT_CONTEXT pc = NULL;
782             while(1) {
783                 pc = ptrCertFindCertificateInStore( hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pc);
784                 if(!pc)
785                     break;
786                 QByteArray der((const char *)(pc->pbCertEncoded), static_cast<int>(pc->cbCertEncoded));
787                 QSslCertificate cert(der, QSsl::Der);
788                 systemCerts.append(cert);
789             }
790             ptrCertCloseStore(hSystemStore, 0);
791         }
792     }
793 #elif defined(Q_OS_UNIX)
794     QSet<QString> certFiles;
795     QList<QByteArray> directories = unixRootCertDirectories();
796     QDir currentDir;
797     QStringList nameFilters;
798     nameFilters << QLatin1String("*.pem") << QLatin1String("*.crt");
799     currentDir.setNameFilters(nameFilters);
800     for (int a = 0; a < directories.count(); a++) {
801         currentDir.setPath(QLatin1String(directories.at(a)));
802         QDirIterator it(currentDir);
803         while(it.hasNext()) {
804             it.next();
805             // use canonical path here to not load the same certificate twice if symlinked
806             certFiles.insert(it.fileInfo().canonicalFilePath());
807         }
808     }
809     QSetIterator<QString> it(certFiles);
810     while(it.hasNext()) {
811         systemCerts.append(QSslCertificate::fromPath(it.next()));
812     }
813     systemCerts.append(QSslCertificate::fromPath(QLatin1String("/etc/pki/tls/certs/ca-bundle.crt"), QSsl::Pem)); // Fedora, Mandriva
814     systemCerts.append(QSslCertificate::fromPath(QLatin1String("/usr/local/share/certs/ca-root-nss.crt"), QSsl::Pem)); // FreeBSD's ca_root_nss
815 #endif
816 #ifdef QSSLSOCKET_DEBUG
817     qDebug() << "systemCaCertificates retrieval time " << timer.elapsed() << "ms";
818     qDebug() << "imported " << systemCerts.count() << " certificates";
819 #endif
820
821     return systemCerts;
822 }
823
824 void QSslSocketBackendPrivate::startClientEncryption()
825 {
826     Q_Q(QSslSocket);
827     if (!initSslContext()) {
828         q->setErrorString(QSslSocket::tr("Unable to init Ssl Context: %1").arg(getErrorsFromOpenSsl()));
829         q->setSocketError(QAbstractSocket::SslInternalError);
830         emit q->error(QAbstractSocket::SslInternalError);
831         return;
832     }
833
834     // Start connecting. This will place outgoing data in the BIO, so we
835     // follow up with calling transmit().
836     startHandshake();
837     transmit();
838 }
839
840 void QSslSocketBackendPrivate::startServerEncryption()
841 {
842     Q_Q(QSslSocket);
843     if (!initSslContext()) {
844         q->setErrorString(QSslSocket::tr("Unable to init Ssl Context: %1").arg(getErrorsFromOpenSsl()));
845         q->setSocketError(QAbstractSocket::SslInternalError);
846         emit q->error(QAbstractSocket::SslInternalError);
847         return;
848     }
849
850     // Start connecting. This will place outgoing data in the BIO, so we
851     // follow up with calling transmit().
852     startHandshake();
853     transmit();
854 }
855
856 /*!
857     \internal
858
859     Transmits encrypted data between the BIOs and the socket.
860 */
861 void QSslSocketBackendPrivate::transmit()
862 {
863     Q_Q(QSslSocket);
864
865     // If we don't have any SSL context, don't bother transmitting.
866     if (!ssl)
867         return;
868
869     bool transmitting;
870     do {
871         transmitting = false;
872
873         // If the connection is secure, we can transfer data from the write
874         // buffer (in plain text) to the write BIO through SSL_write.
875         if (connectionEncrypted && !writeBuffer.isEmpty()) {
876             qint64 totalBytesWritten = 0;
877             int nextDataBlockSize;
878             while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
879                 int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize);
880                 if (writtenBytes <= 0) {
881                     // ### Better error handling.
882                     q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(getErrorsFromOpenSsl()));
883                     q->setSocketError(QAbstractSocket::SslInternalError);
884                     emit q->error(QAbstractSocket::SslInternalError);
885                     return;
886                 }
887 #ifdef QSSLSOCKET_DEBUG
888                 qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes";
889 #endif
890                 writeBuffer.free(writtenBytes);
891                 totalBytesWritten += writtenBytes;
892
893                 if (writtenBytes < nextDataBlockSize) {
894                     // break out of the writing loop and try again after we had read
895                     transmitting = true;
896                     break;
897                 }
898             }
899
900             if (totalBytesWritten > 0) {
901                 // Don't emit bytesWritten() recursively.
902                 if (!emittedBytesWritten) {
903                     emittedBytesWritten = true;
904                     emit q->bytesWritten(totalBytesWritten);
905                     emittedBytesWritten = false;
906                 }
907             }
908         }
909
910         // Check if we've got any data to be written to the socket.
911         QVarLengthArray<char, 4096> data;
912         int pendingBytes;
913         while (plainSocket->isValid() && (pendingBytes = q_BIO_pending(writeBio)) > 0) {
914             // Read encrypted data from the write BIO into a buffer.
915             data.resize(pendingBytes);
916             int encryptedBytesRead = q_BIO_read(writeBio, data.data(), pendingBytes);
917
918             // Write encrypted data from the buffer to the socket.
919             qint64 actualWritten = plainSocket->write(data.constData(), encryptedBytesRead);
920 #ifdef QSSLSOCKET_DEBUG
921             qDebug() << "QSslSocketBackendPrivate::transmit: wrote" << encryptedBytesRead << "encrypted bytes to the socket" << actualWritten << "actual.";
922 #endif
923             if (actualWritten < 0) {
924                 //plain socket write fails if it was in the pending close state.
925                 q->setErrorString(plainSocket->errorString());
926                 q->setSocketError(plainSocket->error());
927                 emit q->error(plainSocket->error());
928                 return;
929             }
930             transmitting = true;
931         }
932
933         // Check if we've got any data to be read from the socket.
934         if (!connectionEncrypted || !readBufferMaxSize || readBuffer.size() < readBufferMaxSize)
935             while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
936                 // Read encrypted data from the socket into a buffer.
937                 data.resize(pendingBytes);
938                 // just peek() here because q_BIO_write could write less data than expected
939                 int encryptedBytesRead = plainSocket->peek(data.data(), pendingBytes);
940 #ifdef QSSLSOCKET_DEBUG
941                 qDebug() << "QSslSocketBackendPrivate::transmit: read" << encryptedBytesRead << "encrypted bytes from the socket";
942 #endif
943                 // Write encrypted data from the buffer into the read BIO.
944                 int writtenToBio = q_BIO_write(readBio, data.constData(), encryptedBytesRead);
945
946                 // do the actual read() here and throw away the results.
947                 if (writtenToBio > 0) {
948                     // ### TODO: make this cheaper by not making it memcpy. E.g. make it work with data=0x0 or make it work with seek
949                     plainSocket->read(data.data(), writtenToBio);
950                 } else {
951                     // ### Better error handling.
952                     q->setErrorString(QSslSocket::tr("Unable to decrypt data: %1").arg(getErrorsFromOpenSsl()));
953                     q->setSocketError(QAbstractSocket::SslInternalError);
954                     emit q->error(QAbstractSocket::SslInternalError);
955                     return;
956                 }
957
958                 transmitting = true;
959             }
960
961         // If the connection isn't secured yet, this is the time to retry the
962         // connect / accept.
963         if (!connectionEncrypted) {
964 #ifdef QSSLSOCKET_DEBUG
965             qDebug() << "QSslSocketBackendPrivate::transmit: testing encryption";
966 #endif
967             if (startHandshake()) {
968 #ifdef QSSLSOCKET_DEBUG
969                 qDebug() << "QSslSocketBackendPrivate::transmit: encryption established";
970 #endif
971                 connectionEncrypted = true;
972                 transmitting = true;
973             } else if (plainSocket->state() != QAbstractSocket::ConnectedState) {
974 #ifdef QSSLSOCKET_DEBUG
975                 qDebug() << "QSslSocketBackendPrivate::transmit: connection lost";
976 #endif
977                 break;
978             } else if (paused) {
979                 // just wait until the user continues
980                 return;
981             } else {
982 #ifdef QSSLSOCKET_DEBUG
983                 qDebug() << "QSslSocketBackendPrivate::transmit: encryption not done yet";
984 #endif
985             }
986         }
987
988         // If the request is small and the remote host closes the transmission
989         // after sending, there's a chance that startHandshake() will already
990         // have triggered a shutdown.
991         if (!ssl)
992             continue;
993
994         // We always read everything from the SSL decryption buffers, even if
995         // we have a readBufferMaxSize. There's no point in leaving data there
996         // just so that readBuffer.size() == readBufferMaxSize.
997         int readBytes = 0;
998         data.resize(4096);
999         ::memset(data.data(), 0, data.size());
1000         do {
1001             // Don't use SSL_pending(). It's very unreliable.
1002             if ((readBytes = q_SSL_read(ssl, data.data(), data.size())) > 0) {
1003 #ifdef QSSLSOCKET_DEBUG
1004                 qDebug() << "QSslSocketBackendPrivate::transmit: decrypted" << readBytes << "bytes";
1005 #endif
1006                 char *ptr = readBuffer.reserve(readBytes);
1007                 ::memcpy(ptr, data.data(), readBytes);
1008
1009                 if (readyReadEmittedPointer)
1010                     *readyReadEmittedPointer = true;
1011                 emit q->readyRead();
1012                 transmitting = true;
1013                 continue;
1014             }
1015
1016             // Error.
1017             switch (q_SSL_get_error(ssl, readBytes)) {
1018             case SSL_ERROR_WANT_READ:
1019             case SSL_ERROR_WANT_WRITE:
1020                 // Out of data.
1021                 break;
1022             case SSL_ERROR_ZERO_RETURN:
1023                 // The remote host closed the connection.
1024 #ifdef QSSLSOCKET_DEBUG
1025                 qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect";
1026 #endif
1027                 plainSocket->disconnectFromHost();
1028                 break;
1029             case SSL_ERROR_SYSCALL: // some IO error
1030             case SSL_ERROR_SSL: // error in the SSL library
1031                 // we do not know exactly what the error is, nor whether we can recover from it,
1032                 // so just return to prevent an endless loop in the outer "while" statement
1033                 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
1034                 q->setSocketError(QAbstractSocket::SslInternalError);
1035                 emit q->error(QAbstractSocket::SslInternalError);
1036                 return;
1037             default:
1038                 // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
1039                 // BIO_s_connect() or BIO_s_accept(), which we do not call.
1040                 // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
1041                 // SSL_CTX_set_client_cert_cb(), which we do not call.
1042                 // So this default case should never be triggered.
1043                 q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(getErrorsFromOpenSsl()));
1044                 q->setSocketError(QAbstractSocket::SslInternalError);
1045                 emit q->error(QAbstractSocket::SslInternalError);
1046                 break;
1047             }
1048         } while (ssl && readBytes > 0);
1049     } while (ssl && ctx && transmitting);
1050 }
1051
1052 static QSslError _q_OpenSSL_to_QSslError(int errorCode, const QSslCertificate &cert)
1053 {
1054     QSslError error;
1055     switch (errorCode) {
1056     case X509_V_OK:
1057         // X509_V_OK is also reported if the peer had no certificate.
1058         break;
1059     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1060         error = QSslError(QSslError::UnableToGetIssuerCertificate, cert); break;
1061     case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
1062         error = QSslError(QSslError::UnableToDecryptCertificateSignature, cert); break;
1063     case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
1064         error = QSslError(QSslError::UnableToDecodeIssuerPublicKey, cert); break;
1065     case X509_V_ERR_CERT_SIGNATURE_FAILURE:
1066         error = QSslError(QSslError::CertificateSignatureFailed, cert); break;
1067     case X509_V_ERR_CERT_NOT_YET_VALID:
1068         error = QSslError(QSslError::CertificateNotYetValid, cert); break;
1069     case X509_V_ERR_CERT_HAS_EXPIRED:
1070         error = QSslError(QSslError::CertificateExpired, cert); break;
1071     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1072         error = QSslError(QSslError::InvalidNotBeforeField, cert); break;
1073     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1074         error = QSslError(QSslError::InvalidNotAfterField, cert); break;
1075     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1076         error = QSslError(QSslError::SelfSignedCertificate, cert); break;
1077     case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1078         error = QSslError(QSslError::SelfSignedCertificateInChain, cert); break;
1079     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1080         error = QSslError(QSslError::UnableToGetLocalIssuerCertificate, cert); break;
1081     case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1082         error = QSslError(QSslError::UnableToVerifyFirstCertificate, cert); break;
1083     case X509_V_ERR_CERT_REVOKED:
1084         error = QSslError(QSslError::CertificateRevoked, cert); break;
1085     case X509_V_ERR_INVALID_CA:
1086         error = QSslError(QSslError::InvalidCaCertificate, cert); break;
1087     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
1088         error = QSslError(QSslError::PathLengthExceeded, cert); break;
1089     case X509_V_ERR_INVALID_PURPOSE:
1090         error = QSslError(QSslError::InvalidPurpose, cert); break;
1091     case X509_V_ERR_CERT_UNTRUSTED:
1092         error = QSslError(QSslError::CertificateUntrusted, cert); break;
1093     case X509_V_ERR_CERT_REJECTED:
1094         error = QSslError(QSslError::CertificateRejected, cert); break;
1095     default:
1096         error = QSslError(QSslError::UnspecifiedError, cert); break;
1097     }
1098     return error;
1099 }
1100
1101 bool QSslSocketBackendPrivate::startHandshake()
1102 {
1103     Q_Q(QSslSocket);
1104
1105     // Check if the connection has been established. Get all errors from the
1106     // verification stage.
1107     _q_sslErrorList()->mutex.lock();
1108     _q_sslErrorList()->errors.clear();
1109     int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
1110
1111     const QList<QPair<int, int> > &lastErrors = _q_sslErrorList()->errors;
1112     for (int i = 0; i < lastErrors.size(); ++i) {
1113         const QPair<int, int> &currentError = lastErrors.at(i);
1114         // Initialize the peer certificate chain in order to find which certificate caused this error
1115         if (configuration.peerCertificateChain.isEmpty())
1116             configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
1117         emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.first,
1118                                 configuration.peerCertificateChain.value(currentError.second)));
1119         if (q->state() != QAbstractSocket::ConnectedState)
1120             break;
1121     }
1122
1123     errorList << lastErrors;
1124     _q_sslErrorList()->mutex.unlock();
1125
1126     // Connection aborted during handshake phase.
1127     if (q->state() != QAbstractSocket::ConnectedState)
1128         return false;
1129
1130     // Check if we're encrypted or not.
1131     if (result <= 0) {
1132         switch (q_SSL_get_error(ssl, result)) {
1133         case SSL_ERROR_WANT_READ:
1134         case SSL_ERROR_WANT_WRITE:
1135             // The handshake is not yet complete.
1136             break;
1137         default:
1138             q->setErrorString(QSslSocket::tr("Error during SSL handshake: %1").arg(getErrorsFromOpenSsl()));
1139             q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
1140 #ifdef QSSLSOCKET_DEBUG
1141             qDebug() << "QSslSocketBackendPrivate::startHandshake: error!" << q->errorString();
1142 #endif
1143             emit q->error(QAbstractSocket::SslHandshakeFailedError);
1144             q->abort();
1145         }
1146         return false;
1147     }
1148
1149     // Store the peer certificate and chain. For clients, the peer certificate
1150     // chain includes the peer certificate; for servers, it doesn't. Both the
1151     // peer certificate and the chain may be empty if the peer didn't present
1152     // any certificate.
1153     if (configuration.peerCertificateChain.isEmpty())
1154         configuration.peerCertificateChain = STACKOFX509_to_QSslCertificates(q_SSL_get_peer_cert_chain(ssl));
1155     X509 *x509 = q_SSL_get_peer_certificate(ssl);
1156     configuration.peerCertificate = QSslCertificatePrivate::QSslCertificate_from_X509(x509);
1157     q_X509_free(x509);
1158
1159     // Start translating errors.
1160     QList<QSslError> errors;
1161
1162     // check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer)
1163     foreach (const QSslCertificate &cert, configuration.peerCertificateChain) {
1164         if (QSslCertificatePrivate::isBlacklisted(cert)) {
1165             QSslError error(QSslError::CertificateBlacklisted, cert);
1166             errors << error;
1167             emit q->peerVerifyError(error);
1168             if (q->state() != QAbstractSocket::ConnectedState)
1169                 return false;
1170         }
1171     }
1172
1173     bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
1174                         || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
1175                             && mode == QSslSocket::SslClientMode);
1176
1177     // Check the peer certificate itself. First try the subject's common name
1178     // (CN) as a wildcard, then try all alternate subject name DNS entries the
1179     // same way.
1180     if (!configuration.peerCertificate.isNull()) {
1181         // but only if we're a client connecting to a server
1182         // if we're the server, don't check CN
1183         if (mode == QSslSocket::SslClientMode) {
1184             QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
1185
1186             if (!isMatchingHostname(configuration.peerCertificate, peerName)) {
1187                 // No matches in common names or alternate names.
1188                 QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
1189                 errors << error;
1190                 emit q->peerVerifyError(error);
1191                 if (q->state() != QAbstractSocket::ConnectedState)
1192                     return false;
1193             }
1194         }
1195     } else {
1196         // No peer certificate presented. Report as error if the socket
1197         // expected one.
1198         if (doVerifyPeer) {
1199             QSslError error(QSslError::NoPeerCertificate);
1200             errors << error;
1201             emit q->peerVerifyError(error);
1202             if (q->state() != QAbstractSocket::ConnectedState)
1203                 return false;
1204         }
1205     }
1206
1207     // Translate errors from the error list into QSslErrors.
1208     for (int i = 0; i < errorList.size(); ++i) {
1209         const QPair<int, int> &errorAndDepth = errorList.at(i);
1210         int err = errorAndDepth.first;
1211         int depth = errorAndDepth.second;
1212         errors << _q_OpenSSL_to_QSslError(err, configuration.peerCertificateChain.value(depth));
1213     }
1214
1215     if (!errors.isEmpty()) {
1216         sslErrors = errors;
1217         emit q->sslErrors(errors);
1218
1219         bool doEmitSslError = !verifyErrorsHaveBeenIgnored();
1220         // check whether we need to emit an SSL handshake error
1221         if (doVerifyPeer && doEmitSslError) {
1222             if (q->pauseMode() & QAbstractSocket::PauseOnNotify) {
1223                 pauseSocketNotifiers(q);
1224                 paused = true;
1225             } else {
1226                 q->setErrorString(sslErrors.first().errorString());
1227                 q->setSocketError(QAbstractSocket::SslHandshakeFailedError);
1228                 emit q->error(QAbstractSocket::SslHandshakeFailedError);
1229                 plainSocket->disconnectFromHost();
1230             }
1231             return false;
1232         }
1233     } else {
1234         sslErrors.clear();
1235     }
1236
1237     continueHandshake();
1238     return true;
1239 }
1240
1241 void QSslSocketBackendPrivate::disconnectFromHost()
1242 {
1243     if (ssl) {
1244         q_SSL_shutdown(ssl);
1245         transmit();
1246     }
1247     plainSocket->disconnectFromHost();
1248 }
1249
1250 void QSslSocketBackendPrivate::disconnected()
1251 {
1252     if (plainSocket->bytesAvailable() <= 0)
1253         destroySslContext();
1254     //if there is still buffered data in the plain socket, don't destroy the ssl context yet.
1255     //it will be destroyed when the socket is deleted.
1256 }
1257
1258 QSslCipher QSslSocketBackendPrivate::sessionCipher() const
1259 {
1260     if (!ssl || !ctx)
1261         return QSslCipher();
1262 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
1263     // FIXME This is fairly evil, but needed to keep source level compatibility
1264     // with the OpenSSL 0.9.x implementation at maximum -- some other functions
1265     // don't take a const SSL_CIPHER* when they should
1266     SSL_CIPHER *sessionCipher = const_cast<SSL_CIPHER *>(q_SSL_get_current_cipher(ssl));
1267 #else
1268     SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl);
1269 #endif
1270     return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher();
1271 }
1272
1273 void QSslSocketBackendPrivate::continueHandshake()
1274 {
1275     Q_Q(QSslSocket);
1276     // if we have a max read buffer size, reset the plain socket's to match
1277     if (readBufferMaxSize)
1278         plainSocket->setReadBufferSize(readBufferMaxSize);
1279
1280     connectionEncrypted = true;
1281     emit q->encrypted();
1282     if (autoStartHandshake && pendingClose) {
1283         pendingClose = false;
1284         q->disconnectFromHost();
1285     }
1286 }
1287
1288 QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509)
1289 {
1290     ensureInitialized();
1291     QList<QSslCertificate> certificates;
1292     for (int i = 0; i < q_sk_X509_num(x509); ++i) {
1293         if (X509 *entry = q_sk_X509_value(x509, i))
1294             certificates << QSslCertificatePrivate::QSslCertificate_from_X509(entry);
1295     }
1296     return certificates;
1297 }
1298
1299 QString QSslSocketBackendPrivate::getErrorsFromOpenSsl()
1300 {
1301     QString errorString;
1302     unsigned long errNum;
1303     while((errNum = q_ERR_get_error())) {
1304         if (! errorString.isEmpty())
1305             errorString.append(QLatin1String(", "));
1306         const char *error = q_ERR_error_string(errNum, NULL);
1307         errorString.append(QString::fromAscii(error)); // error is ascii according to man ERR_error_string
1308     }
1309     return errorString;
1310 }
1311
1312 bool QSslSocketBackendPrivate::isMatchingHostname(const QSslCertificate &cert, const QString &peerName)
1313 {
1314     QStringList commonNameList = cert.subjectInfo(QSslCertificate::CommonName);
1315
1316     foreach (const QString &commonName, commonNameList) {
1317         if (isMatchingHostname(commonName.toLower(), peerName.toLower())) {
1318             return true;
1319         }
1320     }
1321
1322     foreach (const QString &altName, cert.subjectAlternativeNames().values(QSsl::DnsEntry)) {
1323         if (isMatchingHostname(altName.toLower(), peerName.toLower())) {
1324             return true;
1325         }
1326     }
1327
1328     return false;
1329 }
1330
1331 bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QString &hostname)
1332 {
1333     int wildcard = cn.indexOf(QLatin1Char('*'));
1334
1335     // Check this is a wildcard cert, if not then just compare the strings
1336     if (wildcard < 0)
1337         return cn == hostname;
1338
1339     int firstCnDot = cn.indexOf(QLatin1Char('.'));
1340     int secondCnDot = cn.indexOf(QLatin1Char('.'), firstCnDot+1);
1341
1342     // Check at least 3 components
1343     if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.length()))
1344         return false;
1345
1346     // Check * is last character of 1st component (ie. there's a following .)
1347     if (wildcard+1 != firstCnDot)
1348         return false;
1349
1350     // Check only one star
1351     if (cn.lastIndexOf(QLatin1Char('*')) != wildcard)
1352         return false;
1353
1354     // Check characters preceding * (if any) match
1355     if (wildcard && (hostname.leftRef(wildcard) != cn.leftRef(wildcard)))
1356         return false;
1357
1358     // Check characters following first . match
1359     if (hostname.midRef(hostname.indexOf(QLatin1Char('.'))) != cn.midRef(firstCnDot))
1360         return false;
1361
1362     // Check if the hostname is an IP address, if so then wildcards are not allowed
1363     QHostAddress addr(hostname);
1364     if (!addr.isNull())
1365         return false;
1366
1367     // Ok, I guess this was a wildcard CN and the hostname matches.
1368     return true;
1369 }
1370
1371 QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certificateChain, const QString &hostName)
1372 {
1373     QList<QSslError> errors;
1374     if (certificateChain.count() <= 0) {
1375         errors << QSslError(QSslError::UnspecifiedError);
1376         return errors;
1377     }
1378
1379     // Setup the store with the default CA certificates
1380     X509_STORE *certStore = q_X509_STORE_new();
1381     if (!certStore) {
1382         qWarning() << "Unable to create certificate store";
1383         errors << QSslError(QSslError::UnspecifiedError);
1384         return errors;
1385     }
1386
1387     QList<QSslCertificate> expiredCerts;
1388
1389     foreach (const QSslCertificate &caCertificate, QSslSocket::defaultCaCertificates()) {
1390         // add expired certs later, so that the
1391         // valid ones are used before the expired ones
1392         if (caCertificate.expiryDate() < QDateTime::currentDateTime()) {
1393             expiredCerts.append(caCertificate);
1394         } else {
1395             q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
1396         }
1397     }
1398
1399     bool addExpiredCerts = true;
1400 #if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5)
1401     //On Leopard SSL does not work if we add the expired certificates.
1402     if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_5)
1403         addExpiredCerts = false;
1404 #endif
1405     // now add the expired certs
1406     if (addExpiredCerts) {
1407         foreach (const QSslCertificate &caCertificate, expiredCerts) {
1408             q_X509_STORE_add_cert(certStore, reinterpret_cast<X509 *>(caCertificate.handle()));
1409         }
1410     }
1411
1412     QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
1413
1414     // Register a custom callback to get all verification errors.
1415     X509_STORE_set_verify_cb_func(certStore, q_X509Callback);
1416
1417     // Build the chain of intermediate certificates
1418     STACK_OF(X509) *intermediates = 0;
1419     if (certificateChain.length() > 1) {
1420         intermediates = (STACK_OF(X509) *) q_sk_new_null();
1421
1422         if (!intermediates) {
1423             q_X509_STORE_free(certStore);
1424             errors << QSslError(QSslError::UnspecifiedError);
1425             return errors;
1426         }
1427
1428         bool first = true;
1429         foreach (const QSslCertificate &cert, certificateChain) {
1430             if (first) {
1431                 first = false;
1432                 continue;
1433             }
1434 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
1435             q_sk_push( (_STACK *)intermediates, reinterpret_cast<X509 *>(cert.handle()));
1436 #else
1437             q_sk_push( (STACK *)intermediates, reinterpret_cast<X509 *>(cert.handle()));
1438 #endif
1439         }
1440     }
1441
1442     X509_STORE_CTX *storeContext = q_X509_STORE_CTX_new();
1443     if (!storeContext) {
1444         q_X509_STORE_free(certStore);
1445         errors << QSslError(QSslError::UnspecifiedError);
1446         return errors;
1447     }
1448
1449     if (!q_X509_STORE_CTX_init(storeContext, certStore, reinterpret_cast<X509 *>(certificateChain[0].handle()), intermediates)) {
1450         q_X509_STORE_CTX_free(storeContext);
1451         q_X509_STORE_free(certStore);
1452         errors << QSslError(QSslError::UnspecifiedError);
1453         return errors;
1454     }
1455
1456     // Now we can actually perform the verification of the chain we have built.
1457     // We ignore the result of this function since we process errors via the
1458     // callback.
1459     (void) q_X509_verify_cert(storeContext);
1460
1461     q_X509_STORE_CTX_free(storeContext);
1462 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
1463     q_sk_free( (_STACK *) intermediates);
1464 #else
1465     q_sk_free( (STACK *) intermediates);
1466 #endif
1467
1468     // Now process the errors
1469     const QList<QPair<int, int> > errorList = _q_sslErrorList()->errors;
1470     _q_sslErrorList()->errors.clear();
1471
1472     sslErrorListMutexLocker.unlock();
1473
1474     // Translate the errors
1475     if (QSslCertificatePrivate::isBlacklisted(certificateChain[0])) {
1476         QSslError error(QSslError::CertificateBlacklisted, certificateChain[0]);
1477         errors << error;
1478     }
1479
1480     // Check the certificate name against the hostname if one was specified
1481     if ((!hostName.isEmpty()) && (!isMatchingHostname(certificateChain[0], hostName))) {
1482         // No matches in common names or alternate names.
1483         QSslError error(QSslError::HostNameMismatch, certificateChain[0]);
1484         errors << error;
1485     }
1486
1487     // Translate errors from the error list into QSslErrors.
1488     for (int i = 0; i < errorList.size(); ++i) {
1489         const QPair<int, int> &errorAndDepth = errorList.at(i);
1490         int err = errorAndDepth.first;
1491         int depth = errorAndDepth.second;
1492         errors << _q_OpenSSL_to_QSslError(err, certificateChain.value(depth));
1493     }
1494
1495     q_X509_STORE_free(certStore);
1496
1497     return errors;
1498 }
1499
1500 QT_END_NAMESPACE