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