source: trunk/src/network/ssl/qsslsocket.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 69.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43//#define QSSLSOCKET_DEBUG
44
45/*!
46 \class QSslSocket
47 \brief The QSslSocket class provides an SSL encrypted socket for both
48 clients and servers.
49 \since 4.3
50
51 \reentrant
52 \ingroup network
53 \ingroup ssl
54 \inmodule QtNetwork
55
56 QSslSocket establishes a secure, encrypted TCP connection you can
57 use for transmitting encrypted data. It can operate in both client
58 and server mode, and it supports modern SSL protocols, including
59 SSLv3 and TLSv1. By default, QSslSocket uses SSLv3, but you can
60 change the SSL protocol by calling setProtocol() as long as you do
61 it before the handshake has started.
62
63 SSL encryption operates on top of the existing TCP stream after
64 the socket enters the ConnectedState. There are two simple ways to
65 establish a secure connection using QSslSocket: With an immediate
66 SSL handshake, or with a delayed SSL handshake occurring after the
67 connection has been established in unencrypted mode.
68
69 The most common way to use QSslSocket is to construct an object
70 and start a secure connection by calling connectToHostEncrypted().
71 This method starts an immediate SSL handshake once the connection
72 has been established.
73
74 \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 0
75
76 As with a plain QTcpSocket, QSslSocket enters the HostLookupState,
77 ConnectingState, and finally the ConnectedState, if the connection
78 is successful. The handshake then starts automatically, and if it
79 succeeds, the encrypted() signal is emitted to indicate the socket
80 has entered the encrypted state and is ready for use.
81
82 Note that data can be written to the socket immediately after the
83 return from connectToHostEncrypted() (i.e., before the encrypted()
84 signal is emitted). The data is queued in QSslSocket until after
85 the encrypted() signal is emitted.
86
87 An example of using the delayed SSL handshake to secure an
88 existing connection is the case where an SSL server secures an
89 incoming connection. Suppose you create an SSL server class as a
90 subclass of QTcpServer. You would override
91 QTcpServer::incomingConnection() with something like the example
92 below, which first constructs an instance of QSslSocket and then
93 calls setSocketDescriptor() to set the new socket's descriptor to
94 the existing one passed in. It then initiates the SSL handshake
95 by calling startServerEncryption().
96
97 \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 1
98
99 If an error occurs, QSslSocket emits the sslErrors() signal. In this
100 case, if no action is taken to ignore the error(s), the connection
101 is dropped. To continue, despite the occurrence of an error, you
102 can call ignoreSslErrors(), either from within this slot after the
103 error occurs, or any time after construction of the QSslSocket and
104 before the connection is attempted. This will allow QSslSocket to
105 ignore the errors it encounters when establishing the identity of
106 the peer. Ignoring errors during an SSL handshake should be used
107 with caution, since a fundamental characteristic of secure
108 connections is that they should be established with a successful
109 handshake.
110
111 Once encrypted, you use QSslSocket as a regular QTcpSocket. When
112 readyRead() is emitted, you can call read(), canReadLine() and
113 readLine(), or getChar() to read decrypted data from QSslSocket's
114 internal buffer, and you can call write() or putChar() to write
115 data back to the peer. QSslSocket will automatically encrypt the
116 written data for you, and emit encryptedBytesWritten() once
117 the data has been written to the peer.
118
119 As a convenience, QSslSocket supports QTcpSocket's blocking
120 functions waitForConnected(), waitForReadyRead(),
121 waitForBytesWritten(), and waitForDisconnected(). It also provides
122 waitForEncrypted(), which will block the calling thread until an
123 encrypted connection has been established.
124
125 \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 2
126
127 QSslSocket provides an extensive, easy-to-use API for handling
128 cryptographic ciphers, private keys, and local, peer, and
129 Certification Authority (CA) certificates. It also provides an API
130 for handling errors that occur during the handshake phase.
131
132 The following features can also be customized:
133
134 \list
135 \o The socket's cryptographic cipher suite can be customized before
136 the handshake phase with setCiphers() and setDefaultCiphers().
137 \o The socket's local certificate and private key can be customized
138 before the handshake phase with setLocalCertificate() and
139 setPrivateKey().
140 \o The CA certificate database can be extended and customized with
141 addCaCertificate(), addCaCertificates(), setCaCertificates(),
142 addDefaultCaCertificate(), addDefaultCaCertificates(), and
143 setDefaultCaCertificates().
144 \endlist
145
146 For more information about ciphers and certificates, refer to QSslCipher and
147 QSslCertificate.
148
149 This product includes software developed by the OpenSSL Project
150 for use in the OpenSSL Toolkit (\l{http://www.openssl.org/}).
151
152 \note Be aware of the difference between the bytesWritten() signal and
153 the encryptedBytesWritten() signal. For a QTcpSocket, bytesWritten()
154 will get emitted as soon as data has been written to the TCP socket.
155 For a QSslSocket, bytesWritten() will get emitted when the data
156 is being encrypted and encryptedBytesWritten()
157 will get emitted as soon as data has been written to the TCP socket.
158
159 \sa QSslCertificate, QSslCipher, QSslError
160*/
161
162/*!
163 \enum QSslSocket::SslMode
164
165 Describes the connection modes available for QSslSocket.
166
167 \value UnencryptedMode The socket is unencrypted. Its
168 behavior is identical to QTcpSocket.
169
170 \value SslClientMode The socket is a client-side SSL socket.
171 It is either alreayd encrypted, or it is in the SSL handshake
172 phase (see QSslSocket::isEncrypted()).
173
174 \value SslServerMode The socket is a server-side SSL socket.
175 It is either already encrypted, or it is in the SSL handshake
176 phase (see QSslSocket::isEncrypted()).
177*/
178
179/*!
180 \enum QSslSocket::PeerVerifyMode
181 \since 4.4
182
183 Describes the peer verification modes for QSslSocket. The default mode is
184 AutoVerifyPeer, which selects an appropriate mode depending on the
185 socket's QSocket::SslMode.
186
187 \value VerifyNone QSslSocket will not request a certificate from the
188 peer. You can set this mode if you are not interested in the identity of
189 the other side of the connection. The connection will still be encrypted,
190 and your socket will still send its local certificate to the peer if it's
191 requested.
192
193 \value QueryPeer QSslSocket will request a certificate from the peer, but
194 does not require this certificate to be valid. This is useful when you
195 want to display peer certificate details to the user without affecting the
196 actual SSL handshake. This mode is the default for servers.
197
198 \value VerifyPeer QSslSocket will request a certificate from the peer
199 during the SSL handshake phase, and requires that this certificate is
200 valid. On failure, QSslSocket will emit the QSslSocket::sslErrors()
201 signal. This mode is the default for clients.
202
203 \value AutoVerifyPeer QSslSocket will automaticaly use QueryPeer for
204 server sockets and VerifyPeer for client sockets.
205
206 \sa QSslSocket::peerVerifyMode()
207*/
208
209/*!
210 \fn QSslSocket::encrypted()
211
212 This signal is emitted when QSslSocket enters encrypted mode. After this
213 signal has been emitted, QSslSocket::isEncrypted() will return true, and
214 all further transmissions on the socket will be encrypted.
215
216 \sa QSslSocket::connectToHostEncrypted(), QSslSocket::isEncrypted()
217*/
218
219/*!
220 \fn QSslSocket::modeChanged(QSslSocket::SslMode mode)
221
222 This signal is emitted when QSslSocket changes from \l
223 QSslSocket::UnencryptedMode to either \l QSslSocket::SslClientMode or \l
224 QSslSocket::SslServerMode. \a mode is the new mode.
225
226 \sa QSslSocket::mode()
227*/
228
229/*!
230 \fn QSslSocket::encryptedBytesWritten(qint64 written)
231 \since 4.4
232
233 This signal is emitted when QSslSocket writes its encrypted data to the
234 network. The \a written parameter contains the number of bytes that were
235 successfully written.
236
237 \sa QIODevice::bytesWritten()
238*/
239
240/*!
241 \fn void QSslSocket::peerVerifyError(const QSslError &error)
242 \since 4.4
243
244 QSslSocket can emit this signal several times during the SSL handshake,
245 before encryption has been established, to indicate that an error has
246 occurred while establishing the identity of the peer. The \a error is
247 usually an indication that QSslSocket is unable to securely identify the
248 peer.
249
250 This signal provides you with an early indication when something's wrong.
251 By connecting to this signal, you can manually choose to tear down the
252 connection from inside the connected slot before the handshake has
253 completed. If no action is taken, QSslSocket will proceed to emitting
254 QSslSocket::sslErrors().
255
256 \sa sslErrors()
257*/
258
259/*!
260 \fn void QSslSocket::sslErrors(const QList<QSslError> &errors);
261
262 QSslSocket emits this signal after the SSL handshake to indicate that one
263 or more errors have occurred while establishing the identity of the
264 peer. The errors are usually an indication that QSslSocket is unable to
265 securely identify the peer. Unless any action is taken, the connection
266 will be dropped after this signal has been emitted.
267
268 If you want to continue connecting despite the errors that have occurred,
269 you must call QSslSocket::ignoreSslErrors() from inside a slot connected to
270 this signal. If you need to access the error list at a later point, you
271 can call sslErrors() (without arguments).
272
273 \a errors contains one or more errors that prevent QSslSocket from
274 verifying the identity of the peer.
275
276 Note: You cannot use Qt::QueuedConnection when connecting to this signal,
277 or calling QSslSocket::ignoreSslErrors() will have no effect.
278
279 \sa peerVerifyError()
280*/
281
282#include "qsslcipher.h"
283#include "qsslsocket.h"
284#include "qsslsocket_openssl_p.h"
285#include "qsslconfiguration_p.h"
286
287#include <QtCore/qdebug.h>
288#include <QtCore/qdir.h>
289#include <QtCore/qdatetime.h>
290#include <QtCore/qmutex.h>
291#include <QtNetwork/qhostaddress.h>
292#include <QtNetwork/qhostinfo.h>
293
294QT_BEGIN_NAMESPACE
295
296/*
297 Returns the difference between msecs and elapsed. If msecs is -1,
298 however, -1 is returned.
299*/
300static int qt_timeout_value(int msecs, int elapsed)
301{
302 if (msecs == -1)
303 return -1;
304
305 int timeout = msecs - elapsed;
306 return timeout < 0 ? 0 : timeout;
307}
308
309class QSslSocketGlobalData
310{
311public:
312 QSslSocketGlobalData() : config(new QSslConfigurationPrivate) {}
313
314 QMutex mutex;
315 QList<QSslCipher> supportedCiphers;
316 QExplicitlySharedDataPointer<QSslConfigurationPrivate> config;
317};
318Q_GLOBAL_STATIC(QSslSocketGlobalData, globalData)
319
320/*!
321 Constructs a QSslSocket object. \a parent is passed to QObject's
322 constructor. The new socket's \l {QSslCipher} {cipher} suite is
323 set to the one returned by the static method defaultCiphers().
324*/
325QSslSocket::QSslSocket(QObject *parent)
326 : QTcpSocket(*new QSslSocketBackendPrivate, parent)
327{
328 Q_D(QSslSocket);
329#ifdef QSSLSOCKET_DEBUG
330 qDebug() << "QSslSocket::QSslSocket(" << parent << "), this =" << (void *)this;
331#endif
332 d->q_ptr = this;
333 d->init();
334}
335
336/*!
337 Destroys the QSslSocket.
338*/
339QSslSocket::~QSslSocket()
340{
341 Q_D(QSslSocket);
342#ifdef QSSLSOCKET_DEBUG
343 qDebug() << "QSslSocket::~QSslSocket(), this =" << (void *)this;
344#endif
345 delete d->plainSocket;
346 d->plainSocket = 0;
347}
348
349/*!
350 Starts an encrypted connection to the device \a hostName on \a
351 port, using \a mode as the \l OpenMode. This is equivalent to
352 calling connectToHost() to establish the connection, followed by a
353 call to startClientEncryption().
354
355 QSslSocket first enters the HostLookupState. Then, after entering
356 either the event loop or one of the waitFor...() functions, it
357 enters the ConnectingState, emits connected(), and then initiates
358 the SSL client handshake. At each state change, QSslSocket emits
359 signal stateChanged().
360
361 After initiating the SSL client handshake, if the identity of the
362 peer can't be established, signal sslErrors() is emitted. If you
363 want to ignore the errors and continue connecting, you must call
364 ignoreSslErrors(), either from inside a slot function connected to
365 the sslErrors() signal, or prior to entering encrypted mode. If
366 ignoreSslErrors() is not called, the connection is dropped, signal
367 disconnected() is emitted, and QSslSocket returns to the
368 UnconnectedState.
369
370 If the SSL handshake is successful, QSslSocket emits encrypted().
371
372 \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 3
373
374 \bold{Note:} The example above shows that text can be written to
375 the socket immediately after requesting the encrypted connection,
376 before the encrypted() signal has been emitted. In such cases, the
377 text is queued in the object and written to the socket \e after
378 the connection is established and the encrypted() signal has been
379 emitted.
380
381 The default for \a mode is \l ReadWrite.
382
383 If you want to create a QSslSocket on the server side of a connection, you
384 should instead call startServerEncryption() upon receiving the incoming
385 connection through QTcpServer.
386
387 \sa connectToHost(), startClientEncryption(), waitForConnected(), waitForEncrypted()
388*/
389void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode)
390{
391 Q_D(QSslSocket);
392 if (d->state == ConnectedState || d->state == ConnectingState) {
393 qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected");
394 return;
395 }
396
397 d->init();
398 d->autoStartHandshake = true;
399 d->initialized = true;
400
401 // Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
402 // establish the connection immediately (i.e., first attempt).
403 connectToHost(hostName, port, mode);
404}
405
406/*!
407 \since 4.6
408 \overload
409
410 In addition to the original behaviour of connectToHostEncrypted,
411 this overloaded method enables the usage of a different hostname
412 (\a sslPeerName) for the certificate validation instead of
413 the one used for the TCP connection (\a hostName).
414
415 \sa connectToHostEncrypted()
416*/
417void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port,
418 const QString &sslPeerName, OpenMode mode)
419{
420 Q_D(QSslSocket);
421 if (d->state == ConnectedState || d->state == ConnectingState) {
422 qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected");
423 return;
424 }
425
426 d->init();
427 d->autoStartHandshake = true;
428 d->initialized = true;
429 d->verificationPeerName = sslPeerName;
430
431 // Note: When connecting to localhost, some platforms (e.g., HP-UX and some BSDs)
432 // establish the connection immediately (i.e., first attempt).
433 connectToHost(hostName, port, mode);
434}
435
436/*!
437 Initializes QSslSocket with the native socket descriptor \a
438 socketDescriptor. Returns true if \a socketDescriptor is accepted
439 as a valid socket descriptor; otherwise returns false.
440 The socket is opened in the mode specified by \a openMode, and
441 enters the socket state specified by \a state.
442
443 \bold{Note:} It is not possible to initialize two sockets with the same
444 native socket descriptor.
445
446 \sa socketDescriptor()
447*/
448bool QSslSocket::setSocketDescriptor(int socketDescriptor, SocketState state, OpenMode openMode)
449{
450 Q_D(QSslSocket);
451#ifdef QSSLSOCKET_DEBUG
452 qDebug() << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ','
453 << state << ',' << openMode << ')';
454#endif
455 if (!d->plainSocket)
456 d->createPlainSocket(openMode);
457 bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);
458 d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();
459 setSocketError(d->plainSocket->error());
460 setSocketState(state);
461 setOpenMode(openMode);
462 setLocalPort(d->plainSocket->localPort());
463 setLocalAddress(d->plainSocket->localAddress());
464 setPeerPort(d->plainSocket->peerPort());
465 setPeerAddress(d->plainSocket->peerAddress());
466 setPeerName(d->plainSocket->peerName());
467 return retVal;
468}
469
470/*!
471 \since 4.6
472 Sets the given \a option to the value described by \a value.
473
474 \sa socketOption()
475*/
476void QSslSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
477{
478 Q_D(QSslSocket);
479 if (d->plainSocket)
480 d->plainSocket->setSocketOption(option, value);
481}
482
483/*!
484 \since 4.6
485 Returns the value of the \a option option.
486
487 \sa setSocketOption()
488*/
489QVariant QSslSocket::socketOption(QAbstractSocket::SocketOption option)
490{
491 Q_D(QSslSocket);
492 if (d->plainSocket)
493 return d->plainSocket->socketOption(option);
494 else
495 return QVariant();
496}
497
498/*!
499 Returns the current mode for the socket; either UnencryptedMode, where
500 QSslSocket behaves identially to QTcpSocket, or one of SslClientMode or
501 SslServerMode, where the client is either negotiating or in encrypted
502 mode.
503
504 When the mode changes, QSslSocket emits modeChanged()
505
506 \sa SslMode
507*/
508QSslSocket::SslMode QSslSocket::mode() const
509{
510 Q_D(const QSslSocket);
511 return d->mode;
512}
513
514/*!
515 Returns true if the socket is encrypted; otherwise, false is returned.
516
517 An encrypted socket encrypts all data that is written by calling write()
518 or putChar() before the data is written to the network, and decrypts all
519 incoming data as the data is received from the network, before you call
520 read(), readLine() or getChar().
521
522 QSslSocket emits encrypted() when it enters encrypted mode.
523
524 You can call sessionCipher() to find which cryptographic cipher is used to
525 encrypt and decrypt your data.
526
527 \sa mode()
528*/
529bool QSslSocket::isEncrypted() const
530{
531 Q_D(const QSslSocket);
532 return d->connectionEncrypted;
533}
534
535/*!
536 Returns the socket's SSL protocol. By default, \l QSsl::SslV3 is used.
537
538 \sa setProtocol()
539*/
540QSsl::SslProtocol QSslSocket::protocol() const
541{
542 Q_D(const QSslSocket);
543 return d->configuration.protocol;
544}
545
546/*!
547 Sets the socket's SSL protocol to \a protocol. This will affect the next
548 initiated handshake; calling this function on an already-encrypted socket
549 will not affect the socket's protocol.
550*/
551void QSslSocket::setProtocol(QSsl::SslProtocol protocol)
552{
553 Q_D(QSslSocket);
554 d->configuration.protocol = protocol;
555}
556
557/*!
558 \since 4.4
559
560 Returns the socket's verify mode. This mode mode decides whether
561 QSslSocket should request a certificate from the peer (i.e., the client
562 requests a certificate from the server, or a server requesting a
563 certificate from the client), and whether it should require that this
564 certificate is valid.
565
566 The default mode is AutoVerifyPeer, which tells QSslSocket to use
567 VerifyPeer for clients, QueryPeer for clients.
568
569 \sa setPeerVerifyMode(), peerVerifyDepth(), mode()
570*/
571QSslSocket::PeerVerifyMode QSslSocket::peerVerifyMode() const
572{
573 Q_D(const QSslSocket);
574 return d->configuration.peerVerifyMode;
575}
576
577/*!
578 \since 4.4
579
580 Sets the socket's verify mode to \a mode. This mode decides whether
581 QSslSocket should request a certificate from the peer (i.e., the client
582 requests a certificate from the server, or a server requesting a
583 certificate from the client), and whether it should require that this
584 certificate is valid.
585
586 The default mode is AutoVerifyPeer, which tells QSslSocket to use
587 VerifyPeer for clients, QueryPeer for clients.