Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qtlsbackend_st.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qtlsbackend_st_p.h"
5#include "qtlskey_st_p.h"
6#include "qx509_st_p.h"
7#include "qtls_st_p.h"
8
9#include <QtCore/qsysinfo.h>
10#include <QtCore/qmutex.h>
11
13
14using namespace Qt::StringLiterals;
15
16Q_GLOBAL_STATIC(QRecursiveMutex, qt_securetransport_mutex)
17
18Q_LOGGING_CATEGORY(lcSecureTransport, "qt.tlsbackend.securetransport");
19
20namespace QTlsPrivate {
21
22QList<QSslCertificate> systemCaCertificates(); // defined in qsslsocket_mac_shared.cpp
23
24SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode);
25
27{
29 switch (cipher) {
30 // Sorted as in CipherSuite.h (and groupped by their RFC)
31 // TLS addenda using AES, per RFC 3268
32 case TLS_RSA_WITH_AES_128_CBC_SHA:
33 name = "AES128-SHA"_L1;
34 break;
35 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
36 name = "DHE-RSA-AES128-SHA"_L1;
37 break;
38 case TLS_RSA_WITH_AES_256_CBC_SHA:
39 name = "AES256-SHA"_L1;
40 break;
41 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
42 name = "DHE-RSA-AES256-SHA"_L1;
43 break;
44
45 // ECDSA addenda, RFC 4492
46 case TLS_ECDH_ECDSA_WITH_NULL_SHA:
47 name = "ECDH-ECDSA-NULL-SHA"_L1;
48 break;
49 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
50 name = "ECDH-ECDSA-RC4-SHA"_L1;
51 break;
52 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
53 name = "ECDH-ECDSA-DES-CBC3-SHA"_L1;
54 break;
55 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
56 name = "ECDH-ECDSA-AES128-SHA"_L1;
57 break;
58 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
59 name = "ECDH-ECDSA-AES256-SHA"_L1;
60 break;
61 case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
62 name = "ECDHE-ECDSA-NULL-SHA"_L1;
63 break;
64 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
65 name = "ECDHE-ECDSA-RC4-SHA"_L1;
66 break;
67 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
68 name = "ECDHE-ECDSA-DES-CBC3-SHA"_L1;
69 break;
70 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
71 name = "ECDHE-ECDSA-AES128-SHA"_L1;
72 break;
73 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
74 name = "ECDHE-ECDSA-AES256-SHA"_L1;
75 break;
76 case TLS_ECDH_RSA_WITH_NULL_SHA:
77 name = "ECDH-RSA-NULL-SHA"_L1;
78 break;
79 case TLS_ECDH_RSA_WITH_RC4_128_SHA:
80 name = "ECDH-RSA-RC4-SHA"_L1;
81 break;
82 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
83 name = "ECDH-RSA-DES-CBC3-SHA"_L1;
84 break;
85 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
86 name = "ECDH-RSA-AES128-SHA"_L1;
87 break;
88 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
89 name = "ECDH-RSA-AES256-SHA"_L1;
90 break;
91 case TLS_ECDHE_RSA_WITH_NULL_SHA:
92 name = "ECDHE-RSA-NULL-SHA"_L1;
93 break;
94 case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
95 name = "ECDHE-RSA-RC4-SHA"_L1;
96 break;
97 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
98 name = "ECDHE-RSA-DES-CBC3-SHA"_L1;
99 break;
100 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
101 name = "ECDHE-RSA-AES128-SHA"_L1;
102 break;
103 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
104 name = "ECDHE-RSA-AES256-SHA"_L1;
105 break;
106
107 // TLS 1.2 addenda, RFC 5246
108 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
109 name = "DES-CBC3-SHA"_L1;
110 break;
111 case TLS_RSA_WITH_AES_128_CBC_SHA256:
112 name = "AES128-SHA256"_L1;
113 break;
114 case TLS_RSA_WITH_AES_256_CBC_SHA256:
115 name = "AES256-SHA256"_L1;
116 break;
117 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
118 name = "DHE-RSA-DES-CBC3-SHA"_L1;
119 break;
120 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
121 name = "DHE-RSA-AES128-SHA256"_L1;
122 break;
123 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
124 name = "DHE-RSA-AES256-SHA256"_L1;
125 break;
126
127 // Addendum from RFC 4279, TLS PSK
128 // all missing atm.
129
130 // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption
131 // all missing atm.
132
133 // Addenda from rfc 5288 AES Galois Counter Mode (CGM) Cipher Suites for TLS
134 case TLS_RSA_WITH_AES_256_GCM_SHA384:
135 name = "AES256-GCM-SHA384"_L1;
136 break;
137
138 // RFC 5487 - PSK with SHA-256/384 and AES GCM
139 // all missing atm.
140
141 // Addenda from rfc 5289 Elliptic Curve Cipher Suites with HMAC SHA-256/384
142 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
143 name = "ECDHE-ECDSA-AES128-SHA256"_L1;
144 break;
145 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
146 name = "ECDHE-ECDSA-AES256-SHA384"_L1;
147 break;
148 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
149 name = "ECDH-ECDSA-AES128-SHA256"_L1;
150 break;
151 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
152 name = "ECDH-ECDSA-AES256-SHA384"_L1;
153 break;
154 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
155 name = "ECDHE-RSA-AES128-SHA256"_L1;
156 break;
157 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
158 name = "ECDHE-RSA-AES256-SHA384"_L1;
159 break;
160 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
161 name = "ECDH-RSA-AES128-SHA256"_L1;
162 break;
163 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
164 name = "ECDH-RSA-AES256-SHA384"_L1;
165 break;
166
167 // Addenda from rfc 5289 Elliptic Curve Cipher Suites
168 // with SHA-256/384 and AES Galois Counter Mode (GCM)
169 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
170 name = "ECDHE-RSA-AES256-GCM-SHA384"_L1;
171 break;
172
173 // TLS 1.3 standard cipher suites for ChaCha20+Poly1305.
174 // Note: TLS 1.3 ciphersuites do not specify the key exchange
175 // algorithm -- they only specify the symmetric ciphers.
176 case TLS_AES_128_GCM_SHA256:
177 name = "AES128-GCM-SHA256"_L1;
178 break;
179 case TLS_AES_256_GCM_SHA384:
180 name = "AES256-GCM-SHA384"_L1;
181 break;
182 case TLS_CHACHA20_POLY1305_SHA256:
183 name = "CHACHA20-POLY1305-SHA256"_L1;
184 break;
185 case TLS_AES_128_CCM_SHA256:
186 name = "AES128-CCM-SHA256"_L1;
187 break;
188 case TLS_AES_128_CCM_8_SHA256:
189 name = "AES128-CCM8-SHA256"_L1;
190 break;
191 // Addenda from rfc 5289 Elliptic Curve Cipher Suites with
192 // SHA-256/384 and AES Galois Counter Mode (GCM).
193 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
194 name = "ECDHE-ECDSA-AES128-GCM-SHA256"_L1;
195 break;
196 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
197 name = "ECDHE-ECDSA-AES256-GCM-SHA384"_L1;
198 break;
199 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
200 name = "ECDH-ECDSA-AES128-GCM-SHA256"_L1;
201 break;
202 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
203 name = "ECDH-ECDSA-AES256-GCM-SHA384"_L1;
204 break;
205 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
206 name = "ECDHE-RSA-AES128-GCM-SHA256"_L1;
207 break;
208 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
209 name = "ECDH-RSA-AES128-GCM-SHA256"_L1;
210 break;
211 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
212 name = "ECDH-RSA-AES256-GCM-SHA384"_L1;
213 break;
214 // Addenda from rfc 7905 ChaCha20-Poly1305 Cipher Suites for
215 // Transport Layer Security (TLS).
216 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
217 name = "ECDHE-RSA-CHACHA20-POLY1305-SHA256"_L1;
218 break;
219 case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
220 name = "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256"_L1;
221 break;
222 default:
223 return {};
224 }
225
226 return QTlsBackend::createCiphersuite(name, QSsl::TlsV1_2, "TLSv1.2"_L1);
227}
228
229} // namespace QTlsPrivate
230
231bool QSecureTransportBackend::s_loadedCiphersAndCerts = false;
232
234{
235 return "Secure Transport, "_L1 + QSysInfo::prettyProductName();
236}
237
242
244{
245 const QMutexLocker locker(qt_securetransport_mutex());
246 if (s_loadedCiphersAndCerts)
247 return;
248
249 // We have to set it before setDefaultSupportedCiphers,
250 // since this function can trigger static (global)'s initialization
251 // and as a result - recursive ensureInitialized call
252 // from QSslCertificatePrivate's ctor.
253 s_loadedCiphersAndCerts = true;
254
256 if (context) {
257 QList<QSslCipher> ciphers;
258 QList<QSslCipher> defaultCiphers;
259
260 size_t numCiphers = 0;
261 // Fails only if any of parameters is null.
262 SSLGetNumberSupportedCiphers(context, &numCiphers);
263 QList<SSLCipherSuite> cfCiphers(numCiphers);
264 // Fails only if any of parameter is null or number of ciphers is wrong.
265 SSLGetSupportedCiphers(context, cfCiphers.data(), &numCiphers);
266
267 for (size_t i = 0; i < size_t(cfCiphers.size()); ++i) {
269 if (!ciph.isNull()) {
270 ciphers << ciph;
271 if (ciph.usedBits() >= 128)
272 defaultCiphers << ciph;
273 }
274 }
275
276 setDefaultSupportedCiphers(ciphers);
277 setDefaultCiphers(defaultCiphers);
278
280 setDefaultCaCertificates(systemCaCertificates());
281 } else {
282 s_loadedCiphersAndCerts = false;
283 }
284}
285
290
295
300
302{
304}
305
306QList<QSsl::SslProtocol> QSecureTransportBackend::supportedProtocols() const
307{
308 QList<QSsl::SslProtocol> protocols;
309
310 protocols << QSsl::AnyProtocol;
311 protocols << QSsl::SecureProtocols;
314 protocols << QSsl::TlsV1_0;
315 protocols << QSsl::TlsV1_0OrLater;
316 protocols << QSsl::TlsV1_1;
317 protocols << QSsl::TlsV1_1OrLater;
319 protocols << QSsl::TlsV1_2;
320 protocols << QSsl::TlsV1_2OrLater;
321
322 return protocols;
323}
324
325QList<QSsl::SupportedFeature> QSecureTransportBackend::supportedFeatures() const
326{
327 QList<QSsl::SupportedFeature> features;
329
330 return features;
331}
332
333QList<QSsl::ImplementedClass> QSecureTransportBackend::implementedClasses() const
334{
335 QList<QSsl::ImplementedClass> classes;
339
340 return classes;
341}
342
347
352
353QTlsPrivate::TlsCryptograph *QSecureTransportBackend::createTlsCryptograph() const
354{
356}
357
359
360
361#include "moc_qtlsbackend_st_p.cpp"
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:309
QList< QSsl::SslProtocol > supportedProtocols() const override
QList< QSsl::SupportedFeature > supportedFeatures() const override
QTlsPrivate::X509Certificate * createCertificate() const override
QTlsPrivate::TlsCryptograph * createTlsCryptograph() const override
QList< QSsl::ImplementedClass > implementedClasses() const override
virtual void ensureInitialized() const override
QString tlsLibraryVersionString() const override
virtual QString tlsLibraryBuildVersionString() const override
QTlsPrivate::TlsKey * createKey() const override
QString backendName() const override
QTlsPrivate::X509PemReaderPtr X509PemReader() const override
QTlsPrivate::X509DerReaderPtr X509DerReader() const override
QList< QSslCertificate > systemCaCertificates() const override
The QSslCipher class represents an SSL cryptographic cipher.
Definition qsslcipher.h:22
static bool rootCertOnDemandLoadingSupported()
SslMode
Describes the connection modes available for QSslSocket.
Definition qsslsocket.h:33
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString prettyProductName()
Definition qsysinfo.cpp:877
static constexpr const int nameIndexSecureTransport
static const QString builtinBackendNames[]
TlsKey is an abstract class, that allows a TLS plugin to provide an underlying implementation for the...
static QList< QSslCertificate > certificatesFromDer(const QByteArray &der, int count)
static QList< QSslCertificate > certificatesFromPem(const QByteArray &pem, int count)
X509Certificate is an abstract class that allows a TLS backend to provide an implementation of the QS...
@ TlsV1_2OrLater
Definition qssl.h:59
@ SecureProtocols
Definition qssl.h:55
@ TlsV1_2
Definition qssl.h:53
@ AnyProtocol
Definition qssl.h:54
Combined button and popup list for selecting options.
Namespace containing onternal types that TLS backends implement.
QSslCipher QSslCipher_from_SSLCipherSuite(SSLCipherSuite cipher)
QList< QSslCertificate > systemCaCertificates()
QList< QSslCertificate >(*)(const QByteArray &pem, int count) X509PemReaderPtr
SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
Definition qtls_st.cpp:166
X509PemReaderPtr X509DerReaderPtr
static void * context
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_DEPRECATED
#define QT_WARNING_PUSH
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define Q_LOGGING_CATEGORY(name,...)
GLenum mode
GLuint name