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
qssldiffiehellmanparameters.cpp
Go to the documentation of this file.
1// Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
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
6/*!
7 \class QSslDiffieHellmanParameters
8 \brief The QSslDiffieHellmanParameters class provides an interface for Diffie-Hellman parameters for servers.
9 \since 5.8
10
11 \reentrant
12 \ingroup network
13 \ingroup ssl
14 \ingroup shared
15 \inmodule QtNetwork
16
17 QSslDiffieHellmanParameters provides an interface for setting Diffie-Hellman parameters to servers based on QSslSocket.
18
19 \sa QSslSocket, QSslCipher, QSslConfiguration
20*/
21
24#include "qtlsbackend_p.h"
25#include "qsslsocket.h"
26#include "qsslsocket_p.h"
27
28#include <QtCore/qcoreapplication.h>
29#include <QtCore/qatomic.h>
30#include <QtCore/qbytearray.h>
31#include <QtCore/qbytearraymatcher.h>
32#include <QtCore/qiodevice.h>
33#include <QtCore/qdebug.h>
34
36
37// The 2048-bit MODP group from RFC 3526
38Q_AUTOTEST_EXPORT extern const char qssl_dhparams_default_base64[] =
39 "MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmO"
40 "NATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjftawv/XLb0Brft7jhr"
41 "+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXTmmkWP6j9JM9fg2VdI9yjrZYc"
42 "YvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhghfDKQXkYuNs474553LBgOhgObJ4Oi7Aei"
43 "j7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==";
44
45/*!
46 Returns the default QSslDiffieHellmanParameters used by QSslSocket.
47
48 This is currently the 2048-bit MODP group from RFC 3526.
49*/
50QSslDiffieHellmanParameters QSslDiffieHellmanParameters::defaultParameters()
51{
52 QSslDiffieHellmanParameters def;
53 def.d->derData = QByteArray::fromBase64(QByteArray(qssl_dhparams_default_base64));
54 return def;
55}
56
57/*!
58 Constructs an empty QSslDiffieHellmanParameters instance.
59
60 If an empty QSslDiffieHellmanParameters instance is set on a
61 QSslConfiguration object, Diffie-Hellman negotiation will
62 be disabled.
63
64 \sa isValid()
65 \sa QSslConfiguration
66*/
67QSslDiffieHellmanParameters::QSslDiffieHellmanParameters()
68 : d(new QSslDiffieHellmanParametersPrivate)
69{
70 d->ref.ref();
71}
72
73/*!
74 Constructs a QSslDiffieHellmanParameters object using
75 the byte array \a encoded in either PEM or DER form as specified by \a encoding.
76
77 Use the isValid() method on the returned object to
78 check whether the Diffie-Hellman parameters were valid and
79 loaded correctly.
80
81 \sa isValid()
82 \sa QSslConfiguration
83*/
84QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(const QByteArray &encoded, QSsl::EncodingFormat encoding)
85{
86 QSslDiffieHellmanParameters result;
87 const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
88 if (!tlsBackend)
89 return result;
90 switch (encoding) {
91 case QSsl::Der:
92 result.d->initFromDer(encoded);
93 break;
94 case QSsl::Pem:
95 result.d->initFromPem(encoded);
96 break;
97 }
98 return result;
99}
100
101/*!
102 Constructs a QSslDiffieHellmanParameters object by
103 reading from \a device in either PEM or DER form as specified by \a encoding.
104
105 Use the isValid() method on the returned object
106 to check whether the Diffie-Hellman parameters were valid
107 and loaded correctly.
108
109 In particular, if \a device is \nullptr or not open for reading, an invalid
110 object will be returned.
111
112 \sa isValid()
113 \sa QSslConfiguration
114*/
115QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(QIODevice *device, QSsl::EncodingFormat encoding)
116{
117 if (device)
118 return fromEncoded(device->readAll(), encoding);
119 else
120 return QSslDiffieHellmanParameters();
121}
122
123/*!
124 Constructs an identical copy of \a other.
125*/
126QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(const QSslDiffieHellmanParameters &other)
127 : d(other.d)
128{
129 if (d)
130 d->ref.ref();
131}
132
133/*!
134 \fn QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(QSslDiffieHellmanParameters &&other)
135
136 Move-constructs from \a other.
137
138 \note The moved-from object \a other is placed in a partially-formed state, in which
139 the only valid operations are destruction and assignment of a new value.
140*/
141
142/*!
143 Destroys the QSslDiffieHellmanParameters object.
144*/
145QSslDiffieHellmanParameters::~QSslDiffieHellmanParameters()
146{
147 if (d && !d->ref.deref())
148 delete d;
149}
150
151/*!
152 Copies the contents of \a other into this QSslDiffieHellmanParameters, making the two QSslDiffieHellmanParameters
153 identical.
154
155 Returns a reference to this QSslDiffieHellmanParameters.
156*/
157QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(const QSslDiffieHellmanParameters &other)
158{
159 QSslDiffieHellmanParameters copy(other);
160 swap(copy);
161 return *this;
162}
163
164/*!
165 \fn QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(QSslDiffieHellmanParameters &&other)
166
167 Move-assigns \a other to this QSslDiffieHellmanParameters instance.
168
169 \note The moved-from object \a other is placed in a partially-formed state, in which
170 the only valid operations are destruction and assignment of a new value.
171*/
172
173/*!
174 \fn void QSslDiffieHellmanParameters::swap(QSslDiffieHellmanParameters &other)
175 \memberswap{QSslDiffieHellmanParameters}
176*/
177
178/*!
179 Returns \c true if this is a an empty QSslDiffieHellmanParameters instance.
180
181 Setting an empty QSslDiffieHellmanParameters instance on a QSslSocket-based
182 server will disable Diffie-Hellman key exchange.
183*/
184bool QSslDiffieHellmanParameters::isEmpty() const noexcept
185{
186 return d->derData.isNull() && d->error == QSslDiffieHellmanParameters::NoError;
187}
188
189/*!
190 Returns \c true if this is a valid QSslDiffieHellmanParameters; otherwise false.
191
192 This method should be used after constructing a QSslDiffieHellmanParameters
193 object to determine its validity.
194
195 If a QSslDiffieHellmanParameters object is not valid, you can use the error()
196 method to determine what error prevented the object from being constructed.
197
198 \sa error()
199*/
200bool QSslDiffieHellmanParameters::isValid() const noexcept
201{
202 return d->error == QSslDiffieHellmanParameters::NoError;
203}
204
205/*!
206 \enum QSslDiffieHellmanParameters::Error
207
208 Describes a QSslDiffieHellmanParameters error.
209
210 \value NoError No error occurred.
211
212 \value InvalidInputDataError The given input data could not be used to
213 construct a QSslDiffieHellmanParameters
214 object.
215
216 \value UnsafeParametersError The Diffie-Hellman parameters are unsafe
217 and should not be used.
218*/
219
220/*!
221 Returns the error that caused the QSslDiffieHellmanParameters object
222 to be invalid.
223*/
224QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const noexcept
225{
226 return d->error;
227}
228
229/*!
230 Returns a human-readable description of the error that caused the
231 QSslDiffieHellmanParameters object to be invalid.
232*/
233QString QSslDiffieHellmanParameters::errorString() const noexcept
234{
235 switch (d->error) {
236 case QSslDiffieHellmanParameters::NoError:
237 return QCoreApplication::translate("QSslDiffieHellmanParameter", "No error");
238 case QSslDiffieHellmanParameters::InvalidInputDataError:
239 return QCoreApplication::translate("QSslDiffieHellmanParameter", "Invalid input data");
240 case QSslDiffieHellmanParameters::UnsafeParametersError:
241 return QCoreApplication::translate("QSslDiffieHellmanParameter", "The given Diffie-Hellman parameters are deemed unsafe");
242 }
243
244 Q_UNREACHABLE_RETURN(QString());
245}
246
247/*!
248 \fn bool QSslDiffieHellmanParameters::operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept
249 \since 5.8
250
251 Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false.
252*/
253
254/*!
255 \fn bool QSslDiffieHellmanParameters::operator!=(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept
256 \since 5.8
257
258 Returns \c true if \a lhs is not equal to \a rhs; otherwise returns \c false.
259*/
260
261/*!
262 \internal
263*/
264bool QSslDiffieHellmanParameters::isEqual(const QSslDiffieHellmanParameters &other) const noexcept
265{
266 return d->derData == other.d->derData;
267}
268
269/*!
270 \internal
271*/
272void QSslDiffieHellmanParametersPrivate::initFromDer(const QByteArray &der)
273{
274 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
275 error = QSslDiffieHellmanParameters::Error(tlsBackend->dhParametersFromDer(der, &derData));
276}
277
278/*!
279 \internal
280*/
281void QSslDiffieHellmanParametersPrivate::initFromPem(const QByteArray &pem)
282{
283 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse())
284 error = QSslDiffieHellmanParameters::Error(tlsBackend->dhParametersFromPem(pem, &derData));
285}
286
287#ifndef QT_NO_DEBUG_STREAM
288/*!
289 \since 5.8
290 \relates QSslDiffieHellmanParameters
291
292 Writes the set of Diffie-Hellman parameters in \a dhparam into the debug object \a debug for
293 debugging purposes.
294
295 The Diffie-Hellman parameters will be represented in Base64-encoded DER form.
296
297 \sa {Debugging Techniques}
298*/
299QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam)
300{
301 QDebugStateSaver saver(debug);
302 debug.resetFormat().nospace();
303 debug << "QSslDiffieHellmanParameters(" << dhparam.d->derData.toBase64() << ')';
304 return debug;
305}
306#endif
307
308/*!
309 \fn size_t qHash(const QSslDiffieHellmanParameters &key, size_t seed)
310 \since 5.8
311 \qhashold{QSslDiffieHellmanParameters}
312*/
313size_t qHash(const QSslDiffieHellmanParameters &dhparam, size_t seed) noexcept
314{
315 return qHash(dhparam.d->derData, seed);
316}
317
318QT_END_NAMESPACE
size_t qHash(const QSslDiffieHellmanParameters &dhparam, size_t seed) noexcept