1// Copyright (C) 2023 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
5#include <QtCore/qfile.h>
6#include <QtNetwork/qsslcipher.h>
7#include "qqmlsslconfiguration_p.h"
8#include <array>
9
10QT_BEGIN_NAMESPACE
11static constexpr std::array<QSsl::SslOption, 8> SslOptions = {
12 QSsl::SslOptionDisableEmptyFragments,
13 QSsl::SslOptionDisableSessionTickets,
14 QSsl::SslOptionDisableCompression,
15 QSsl::SslOptionDisableServerNameIndication,
16 QSsl::SslOptionDisableLegacyRenegotiation,
17 QSsl::SslOptionDisableSessionSharing,
18 QSsl::SslOptionDisableSessionPersistence,
19 QSsl::SslOptionDisableServerCipherPreference
20};
21
22QString QQmlSslConfiguration::ciphers() const
23{
24 return m_ciphers;
25}
26
27QList<QSsl::SslOption> QQmlSslConfiguration::sslOptions() const
28{
29 return m_sslOptions;
30}
31
32QSsl::SslProtocol QQmlSslConfiguration::protocol() const
33{
34 return m_configuration.protocol();
35}
36
37QSslSocket::PeerVerifyMode QQmlSslConfiguration::peerVerifyMode() const
38{
39 return m_configuration.peerVerifyMode();
40}
41
42int QQmlSslConfiguration::peerVerifyDepth() const
43{
44 return m_configuration.peerVerifyDepth();
45}
46
47QByteArray QQmlSslConfiguration::sessionTicket() const
48{
49 return m_configuration.sessionTicket();
50}
51
52QSslConfiguration const QQmlSslConfiguration::configuration()
53{
54 return m_configuration;
55}
56
57void QQmlSslConfiguration::setCertificateFiles(const QStringList &certificateFiles)
58{
59 if (m_certificateFiles == certificateFiles)
60 return;
61
62 m_certificateFiles = certificateFiles;
63 QList<QSslCertificate> certificates;
64 for (const QString &fileName: m_certificateFiles) {
65 QFile certificateFile(fileName);
66 if (certificateFile.open(flags: QIODevice::ReadOnly)) {
67 QByteArray cert = certificateFile.readAll();
68 certificates.append(t: QSslCertificate(cert));
69 } else {
70 qWarning() << "File: " << fileName << "is not found. It will be skipped.";
71 }
72 }
73
74 if (!certificates.isEmpty())
75 m_configuration.setCaCertificates(certificates);
76 else
77 qWarning() << "No certificates loaded.";
78}
79
80void QQmlSslConfiguration::setProtocol(QSsl::SslProtocol protocol)
81{
82 if (m_configuration.protocol() == protocol)
83 return;
84
85 m_configuration.setProtocol(protocol);
86}
87
88void QQmlSslConfiguration::setPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
89{
90 if (m_configuration.peerVerifyMode() == mode)
91 return;
92
93 m_configuration.setPeerVerifyMode(mode);
94}
95
96void QQmlSslConfiguration::setPeerVerifyDepth(int depth)
97{
98 if (m_configuration.peerVerifyDepth() == depth)
99 return;
100
101 m_configuration.setPeerVerifyDepth(depth);
102}
103
104void QQmlSslConfiguration::setCiphers(const QString &ciphers)
105{
106 if (ciphers == m_ciphers)
107 return;
108
109 m_ciphers = ciphers;
110 m_configuration.setCiphers(ciphers); // split(":") is used inside
111}
112
113void QQmlSslConfiguration::setSslOptions(const QList<QSsl::SslOption> &options)
114{
115 if (m_sslOptions == options)
116 return;
117
118 m_sslOptions = options;
119 for (QSsl::SslOption option: m_sslOptions)
120 m_configuration.setSslOption(option, on: true);
121}
122
123void QQmlSslConfiguration::setSessionTicket(const QByteArray &sessionTicket)
124{
125 if (m_configuration.sessionTicket() == sessionTicket)
126 return;
127
128 m_configuration.setSessionTicket(sessionTicket);
129}
130
131void QQmlSslConfiguration::setPrivateKey(const QQmlSslKey &privateKey)
132{
133 m_configuration.setPrivateKey(privateKey.getSslKey());
134}
135
136void QQmlSslConfiguration::setSslOptionsList(const QSslConfiguration &configuration)
137{
138 Q_ASSERT(m_sslOptions.isEmpty());
139 for (QSsl::SslOption option: SslOptions) {
140 if (configuration.testSslOption(option))
141 m_sslOptions.append(t: option);
142 }
143}
144
145void QQmlSslConfiguration::setCiphersList(const QSslConfiguration &configuration)
146{
147 Q_ASSERT(m_ciphers.isEmpty());
148 QList<QSslCipher> ciphers = configuration.ciphers();
149 for (int i = 0; i < ciphers.size(); ++i) {
150 if (i != 0) {
151 m_ciphers += QString::fromUtf8(utf8: ":");
152 }
153 m_ciphers += ciphers[i].name();
154 }
155}
156
157QQmlSslDefaultConfiguration::QQmlSslDefaultConfiguration()
158 : QQmlSslConfiguration()
159{
160 m_configuration = QSslConfiguration::defaultConfiguration();
161 setSslOptionsList(m_configuration);
162 setCiphersList(m_configuration);
163}
164
165QQmlSslDefaultDtlsConfiguration::QQmlSslDefaultDtlsConfiguration()
166 : QQmlSslConfiguration()
167{
168#if QT_CONFIG(dtls)
169 m_configuration = QSslConfiguration::defaultDtlsConfiguration();
170#else
171 qWarning() << "No dtls support enabled";
172 m_configuration = QSslConfiguration::defaultConfiguration();
173#endif // QT_CONFIG(dtls)
174 setSslOptionsList(m_configuration);
175 setCiphersList(m_configuration);
176}
177
178QT_END_NAMESPACE
179

source code of qtdeclarative/src/qmlnetwork/ssl/qqmlsslconfiguration.cpp