The code below shows how to create an SSL client.
#include <QtCrypto>
#include <QCoreApplication>
#include <QTcpSocket>
#ifdef QT_STATICPLUGIN
#include "import_plugins.h"
#endif
char exampleCA_cert[] =
"-----BEGIN CERTIFICATE-----\n"
"MIICSzCCAbSgAwIBAgIBADANBgkqhkiG9w0BAQUFADA4MRMwEQYDVQQDEwpFeGFt\n"
"cGxlIENBMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRXhhbXBsZSBPcmcwHhcNMDYw\n"
"MzE1MDY1ODMyWhcNMDYwNDE1MDY1ODMyWjA4MRMwEQYDVQQDEwpFeGFtcGxlIENB\n"
"MQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRXhhbXBsZSBPcmcwgZ8wDQYJKoZIhvcN\n"
"AQEBBQADgY0AMIGJAoGBAL6ULdOxmpeZ+G/ypV12eNO4qnHSVIPTrYPkQuweXqPy\n"
"atwGFheG+hLVsNIh9GGOS0tCe7a3hBBKN0BJg1ppfk2x39cDx7hefYqjBuZvp/0O\n"
"8Ja3qlQiJLezITZKLxMBrsibcvcuH8zpfUdys2yaN+YGeqNfjQuoNN3Byl1TwuGJ\n"
"AgMBAAGjZTBjMB0GA1UdDgQWBBSQKCUCLNM7uKrAt5o7qv/yQm6qEzASBgNVHRMB\n"
"Af8ECDAGAQEBAgEIMB4GA1UdEQQXMBWBE2V4YW1wbGVAZXhhbXBsZS5jb20wDgYD\n"
"VR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAAh+SIeT1Ao5qInw8oMSoTdO\n"
"lQ6h67ec/Jk5KmK4OoskuimmHI0Sp0C5kOCLehXbsVWW8pXsNC2fv0d2HkdaSUcX\n"
"hwLzqgyZXd4mupIYlaOTZhuHDwWPCAOZS4LVsi2tndTRHKCP12441JjNKhmZRhkR\n"
"u5zzD60nWgM9dKTaxuZM\n"
"-----END CERTIFICATE-----\n";
{
printf("-- Cert --\n");
printf(
" CN: %s\n", qPrintable(cert.
commonName()));
printf(" Valid from: %s, until %s\n",
printf(
" PEM:\n%s\n", qPrintable(cert.
toPEM()));
}
{
QString s;
switch (v) {
s = QStringLiteral("Validated");
break;
s = QStringLiteral("Root CA is marked to reject the specified purpose");
break;
s = QStringLiteral("Certificate not trusted for the required purpose");
break;
s = QStringLiteral("Invalid signature");
break;
s = QStringLiteral("Invalid CA certificate");
break;
s = QStringLiteral("Invalid certificate purpose");
break;
s = QStringLiteral("Certificate is self-signed");
break;
s = QStringLiteral("Certificate has been revoked");
break;
s = QStringLiteral("Maximum certificate chain length exceeded");
break;
s = QStringLiteral("Certificate has expired");
break;
s = QStringLiteral("CA has expired");
break;
default:
s = QStringLiteral("General certificate validation error");
break;
}
return s;
}
{
Q_OBJECT
public:
SecureTest()
{
sock_done = false;
ssl_done = false;
sock = new QTcpSocket;
connect(sock, &QTcpSocket::connected, this, &SecureTest::sock_connected);
connect(sock, &QTcpSocket::readyRead, this, &SecureTest::sock_readyRead);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
connect(sock, &QTcpSocket::errorOccurred, this, &SecureTest::sock_error);
#else
connect(sock, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &SecureTest::sock_error);
#endif
}
~SecureTest() override
{
delete ssl;
delete sock;
}
void start(const QString &_host)
{
int n = _host.indexOf(QLatin1Char(':'));
int port;
if (n != -1) {
host = _host.mid(0, n);
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
port = QStringView(_host).mid(n + 1).toInt();
#else
port = _host.midRef(n + 1).toInt();
#endif
} else {
host = _host;
port = 443;
}
printf("Trying %s:%d...\n", qPrintable(host), port);
sock->connectToHost(host, port);
}
Q_SIGNALS:
void quit();
private Q_SLOTS:
void sock_connected()
{
printf("Connected, starting TLS handshake...\n");
printf("Warning: no root certs\n");
else
}
void sock_readyRead()
{
}
void sock_connectionClosed()
{
printf("\nConnection closed.\n");
sock_done = true;
if (ssl_done && sock_done)
emit quit();
}
void sock_error(QAbstractSocket::SocketError x)
{
if (x == QAbstractSocket::RemoteHostClosedError) {
sock_connectionClosed();
return;
}
printf("\nSocket error.\n");
emit quit();
}
void ssl_handshaken()
{
printf("Successful SSL handshake using %s (%i of %i bits)\n",
if (!cert.isNull())
showCertInfo(cert);
}
QString str = QStringLiteral("Peer Identity: ");
str += QStringLiteral("Valid");
str += QStringLiteral("Error: Wrong certificate");
str += QStringLiteral("Error: Invalid certificate.\n -> Reason: ") +
else
str += QStringLiteral("Error: No certificate");
printf("%s\n", qPrintable(str));
printf("Let's try a GET request now.\n");
QString req = QStringLiteral("GET / HTTP/1.0\nHost: ") + host + QStringLiteral("\n\n");
ssl->
write(req.toLatin1());
}
void ssl_certificateRequested()
{
printf("Server requested client certificate.\n");
if (!issuerList.isEmpty()) {
printf("Allowed issuers:\n");
printf(
" %s\n", qPrintable(i.
toString()));
}
}
void ssl_readyRead()
{
QByteArray a = ssl->
read();
printf("%s", a.data());
}
void ssl_readyReadOutgoing()
{
}
void ssl_closed()
{
printf("SSL session closed.\n");
ssl_done = true;
if (ssl_done && sock_done)
emit quit();
}
void ssl_error()
{
printf("SSL Handshake Error!\n");
emit quit();
} else {
printf("SSL Error!\n");
emit quit();
}
}
private:
QString host;
QTcpSocket *sock;
bool sock_done, ssl_done;
};
#include "ssltest.moc"
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString host = argc > 1 ? QString::fromLocal8Bit(argv[1]) : QStringLiteral("andbit.net");
printf("TLS not supported!\n");
return 1;
}
SecureTest *s = new SecureTest;
QObject::connect(s, &SecureTest::quit, &app, &QCoreApplication::quit);
s->start(host);
app.exec();
delete s;
return 0;
}
const Certificate & primary() const
Return the primary (end-user) Certificate.
Definition qca_cert.h:1249
Bundle of Certificates and CRLs.
Definition qca_cert.h:1929
void addCertificate(const Certificate &cert)
Append a Certificate to this collection.
Ordered certificate properties type.
Definition qca_cert.h:548
QString toString() const
Convert to RFC 1779 string format.
Definition qca_cert.h:577
Public Key (X.509) certificate.
Definition qca_cert.h:857
static Certificate fromPEM(const QString &s, ConvertResult *result=nullptr, const QString &provider=QString())
Import the certificate from PEM format.
QString commonName() const
The common name of the subject of the certificate.
QDateTime notValidBefore() const
The earliest date that the certificate is valid.
QString toPEM() const
Export the Certificate into a PEM format.
QDateTime notValidAfter() const
The latest date that the certificate is valid.
Convenience method for initialising and cleaning up QCA.
Definition qca_core.h:660
void error()
This signal is emitted when an error is detected.
void readyReadOutgoing()
This signal is emitted when SecureLayer has encrypted (network side) data ready to be read.
void closed()
This signal is emitted when the SecureLayer connection is closed.
void readyRead()
This signal is emitted when SecureLayer has decrypted (application side) data ready to be read.
Transport Layer Security / Secure Socket Layer.
Definition qca_securelayer.h:290
int cipherMaxBits() const
The number of bits of security that the cipher could use.
void write(const QByteArray &a) override
This method writes unencrypted (plain) data to the SecureLayer implementation.
void startClient(const QString &host=QString())
Start the TLS/SSL connection as a client.
void writeIncoming(const QByteArray &a) override
This method accepts encoded (typically encrypted) data for processing.
void continueAfterStep()
Resumes TLS processing.
int cipherBits() const
The number of effective bits of security being used for this connection.
@ ErrorHandshake
problem during the negotiation
Definition qca_securelayer.h:322
void setTrustedCertificates(const CertificateCollection &trusted)
Set up the set of trusted certificates that will be used to verify that the certificate provided is v...
QList< CertificateInfoOrdered > issuerList() const
IdentityResult peerIdentityResult() const
After the SSL/TLS handshake is complete, this method allows you to determine if the other end of the ...
QByteArray readOutgoing(int *plainBytes=nullptr) override
This method provides encoded (typically encrypted) data.
IdentityResult
Type of identity.
Definition qca_securelayer.h:330
@ HostMismatch
valid cert provided, but wrong owner
Definition qca_securelayer.h:332
@ InvalidCertificate
invalid cert
Definition qca_securelayer.h:333
@ Valid
identity is verified
Definition qca_securelayer.h:331
@ NoCertificate
identity unknown
Definition qca_securelayer.h:334
QByteArray read() override
This method reads decrypted (plain) data from the SecureLayer implementation.
Validity peerCertificateValidity() const
After the SSL/TLS handshake is valid, this method allows you to check if the received certificate fro...
Error errorCode() const
This method returns the type of error that has occurred.
CertificateChain peerCertificateChain() const
The CertificateChain from the peer (other end of the connection to the trusted root certificate).
QString cipherSuite() const
The cipher suite that has been negotiated for this connection.
void handshaken()
Emitted when the protocol handshake is complete.
void certificateRequested()
Emitted when the server requests a certificate.
QCA_EXPORT void init()
Initialise QCA.
Validity
The validity (or otherwise) of a certificate.
Definition qca_cert.h:497
@ ErrorValidityUnknown
Validity is unknown.
Definition qca_cert.h:510
@ ErrorRevoked
The certificate has been revoked.
Definition qca_cert.h:505
@ ErrorUntrusted
The certificate is not trusted.
Definition qca_cert.h:500
@ ErrorExpired
The certificate has expired, or is not yet valid (e.g.
Definition qca_cert.h:507
@ ErrorPathLengthExceeded
The path length from the root CA to this certificate is too long.
Definition qca_cert.h:506
@ ErrorSignatureFailed
The signature does not match.
Definition qca_cert.h:501
@ ErrorInvalidPurpose
The purpose does not match the intended usage.
Definition qca_cert.h:503
@ ErrorExpiredCA
The Certificate Authority has expired.
Definition qca_cert.h:509
@ ErrorSelfSigned
The certificate is self-signed, and is not found in the list of trusted certificates.
Definition qca_cert.h:504
@ ErrorInvalidCA
The Certificate Authority is invalid.
Definition qca_cert.h:502
@ ValidityGood
The certificate is valid.
Definition qca_cert.h:498
@ ErrorRejected
The root CA rejected the certificate purpose.
Definition qca_cert.h:499
QCA_EXPORT bool haveSystemStore()
Test if QCA can access the root CA certificates.
QCA_EXPORT bool isSupported(const char *features, const QString &provider=QString())
Test if a capability (algorithm) is available.
QCA_EXPORT CertificateCollection systemStore()
Get system-wide root Certificate Authority (CA) certificates.