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