QSslSocket Class
The QSslSocket class provides an SSL encrypted socket for both clients and servers. More...
| Header: | #include <QSslSocket> |
| qmake: | QT += network |
| Since: | Qt 4.3 |
| Inherits: | QTcpSocket |
This class was introduced in Qt 4.3.
Note: All functions in this class are reentrant.
Public Types
| enum | PeerVerifyMode { VerifyNone, QueryPeer, VerifyPeer, AutoVerifyPeer } |
| enum | SslMode { UnencryptedMode, SslClientMode, SslServerMode } |
Detailed Description
QSslSocket establishes a secure, encrypted TCP connection you can use for transmitting encrypted data. It can operate in both client and server mode, and it supports modern SSL protocols, including SSL 3 and TLS 1.2. By default, QSslSocket uses only SSL protocols which are considered to be secure (QSsl::SecureProtocols), but you can change the SSL protocol by calling setProtocol() as long as you do it before the handshake has started.
SSL encryption operates on top of the existing TCP stream after the socket enters the ConnectedState. There are two simple ways to establish a secure connection using QSslSocket: With an immediate SSL handshake, or with a delayed SSL handshake occurring after the connection has been established in unencrypted mode.
The most common way to use QSslSocket is to construct an object and start a secure connection by calling connectToHostEncrypted(). This method starts an immediate SSL handshake once the connection has been established.
QSslSocket *socket = new QSslSocket(this); connect(socket, SIGNAL(encrypted()), this, SLOT(ready())); socket->connectToHostEncrypted("imap.example.com", 993);
As with a plain QTcpSocket, QSslSocket enters the HostLookupState, ConnectingState, and finally the ConnectedState, if the connection is successful. The handshake then starts automatically, and if it succeeds, the encrypted() signal is emitted to indicate the socket has entered the encrypted state and is ready for use.
Note that data can be written to the socket immediately after the return from connectToHostEncrypted() (i.e., before the encrypted() signal is emitted). The data is queued in QSslSocket until after the encrypted() signal is emitted.
An example of using the delayed SSL handshake to secure an existing connection is the case where an SSL server secures an incoming connection. Suppose you create an SSL server class as a subclass of QTcpServer. You would override QTcpServer::incomingConnection() with something like the example below, which first constructs an instance of QSslSocket and then calls setSocketDescriptor() to set the new socket's descriptor to the existing one passed in. It then initiates the SSL handshake by calling startServerEncryption().
void SslServer::incomingConnection(qintptr socketDescriptor) { QSslSocket *serverSocket = new QSslSocket; if (serverSocket->setSocketDescriptor(socketDescriptor)) { addPendingConnection(serverSocket); connect(serverSocket, &QSslSocket::encrypted, this, &SslServer::ready); serverSocket->startServerEncryption(); } else { delete serverSocket; } }
If an error occurs, QSslSocket emits the sslErrors() signal. In this case, if no action is taken to ignore the error(s), the connection is dropped. To continue, despite the occurrence of an error, you can call ignoreSslErrors(), either from within this slot after the error occurs, or any time after construction of the QSslSocket and before the connection is attempted. This will allow QSslSocket to ignore the errors it encounters when establishing the identity of the peer. Ignoring errors during an SSL handshake should be used with caution, since a fundamental characteristic of secure connections is that they should be established with a successful handshake.
Once encrypted, you use QSslSocket as a regular QTcpSocket. When readyRead() is emitted, you can call read(), canReadLine() and readLine(), or getChar() to read decrypted data from QSslSocket's internal buffer, and you can call write() or putChar() to write data back to the peer. QSslSocket will automatically encrypt the written data for you, and emit encryptedBytesWritten() once the data has been written to the peer.
As a convenience, QSslSocket supports QTcpSocket's blocking functions waitForConnected(), waitForReadyRead(), waitForBytesWritten(), and waitForDisconnected(). It also provides waitForEncrypted(), which will block the calling thread until an encrypted connection has been established.
QSslSocket socket; socket.connectToHostEncrypted("http.example.com", 443); if (!socket.waitForEncrypted()) { qDebug() << socket.errorString(); return false; } socket.write("GET / HTTP/1.0\r\n\r\n"); while (socket.waitForReadyRead()) qDebug() << socket.readAll().data();
QSslSocket provides an extensive, easy-to-use API for handling cryptographic ciphers, private keys, and local, peer, and Certification Authority (CA) certificates. It also provides an API for handling errors that occur during the handshake phase.
The following features can also be customized:
- The socket's cryptographic cipher suite can be customized before the handshake phase with QSslConfiguration::setCiphers() and QSslConfiguration::setDefaultCiphers().
- The socket's local certificate and private key can be customized before the handshake phase with setLocalCertificate() and setPrivateKey().
- The CA certificate database can be extended and customized with QSslConfiguration::addCaCertificate(), QSslConfiguration::addCaCertificates().
To extend the list of default CA certificates used by the SSL sockets during the SSL handshake you must update the default configuration, as in the snippet below:
QList<QSslCertificate> certificates = getCertificates(); QSslConfiguration configuration = QSslConfiguration::defaultConfiguration(); configuration.addCaCertificates(certificates); QSslConfiguration::setDefaultConfiguration(configuration);
Note: If available, root certificates on Unix (excluding macOS) will be loaded on demand from the standard certificate directories. If you do not want to load root certificates on demand, you need to call either QSslConfiguration::defaultConfiguration().setCaCertificates() before the first SSL handshake is made in your application (for example, via passing QSslSocket::systemCaCertificates() to it), or call QSslConfiguration::defaultConfiguration()::setCaCertificates() on your QSslSocket instance prior to the SSL handshake.
For more information about ciphers and certificates, refer to QSslCipher and QSslCertificate.
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/).
Note: Be aware of the difference between the bytesWritten() signal and the encryptedBytesWritten() signal. For a QTcpSocket, bytesWritten() will get emitted as soon as data has been written to the TCP socket. For a QSslSocket, bytesWritten() will get emitted when the data is being encrypted and encryptedBytesWritten() will get emitted as soon as data has been written to the TCP socket.
See also QSslCertificate, QSslCipher, and QSslError.
Member Type Documentation
enum QSslSocket::PeerVerifyMode
Describes the peer verification modes for QSslSocket. The default mode is AutoVerifyPeer, which selects an appropriate mode depending on the socket's QSocket::SslMode.
| Constant | Value | Description |
|---|---|---|
QSslSocket::VerifyNone | 0 | QSslSocket will not request a certificate from the peer. You can set this mode if you are not interested in the identity of the other side of the connection. The connection will still be encrypted, and your socket will still send its local certificate to the peer if it's requested. |
QSslSocket::QueryPeer | 1 | QSslSocket will request a certificate from the peer, but does not require this certificate to be valid. This is useful when you want to display peer certificate details to the user without affecting the actual SSL handshake. This mode is the default for servers. Note: In Schannel this value acts the same as VerifyNone. |
QSslSocket::VerifyPeer | 2 | QSslSocket will request a certificate from the peer during the SSL handshake phase, and requires that this certificate is valid. On failure, QSslSocket will emit the QSslSocket::sslErrors() signal. This mode is the default for clients. |
QSslSocket::AutoVerifyPeer | 3 | QSslSocket will automatically use QueryPeer for server sockets and VerifyPeer for client sockets. |
This enum was introduced or modified in Qt 4.4.
See also QSslSocket::peerVerifyMode().
enum QSslSocket::SslMode
Describes the connection modes available for QSslSocket.
| Constant | Value | Description |
|---|---|---|
QSslSocket::UnencryptedMode | 0 | The socket is unencrypted. Its behavior is identical to QTcpSocket. |
QSslSocket::SslClientMode | 1 | The socket is a client-side SSL socket. It is either already encrypted, or it is in the SSL handshake phase (see QSslSocket::isEncrypted()). |
QSslSocket::SslServerMode | 2 | The socket is a server-side SSL socket. It is either already encrypted, or it is in the SSL handshake phase (see QSslSocket::isEncrypted()). |