1/****************************************************************************
2**
3** Copyright (C) 2015 Mikkel Krautz <mikkel@krautz.dk>
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtNetwork module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40
41/*!
42 \class QSslDiffieHellmanParameters
43 \brief The QSslDiffieHellmanParameters class provides an interface for Diffie-Hellman parameters for servers.
44 \since 5.8
45
46 \reentrant
47 \ingroup network
48 \ingroup ssl
49 \ingroup shared
50 \inmodule QtNetwork
51
52 QSslDiffieHellmanParameters provides an interface for setting Diffie-Hellman parameters to servers based on QSslSocket.
53
54 \sa QSslSocket, QSslCipher, QSslConfiguration
55*/
56
57#include "qssldiffiehellmanparameters.h"
58#include "qssldiffiehellmanparameters_p.h"
59#include "qsslsocket.h"
60#include "qsslsocket_p.h"
61
62#include <QtCore/qcoreapplication.h>
63#include <QtCore/qatomic.h>
64#include <QtCore/qbytearray.h>
65#include <QtCore/qbytearraymatcher.h>
66#include <QtCore/qiodevice.h>
67#include <QtCore/qdebug.h>
68
69QT_BEGIN_NAMESPACE
70
71// The 1024-bit MODP group from RFC 2459 (Second Oakley Group)
72Q_AUTOTEST_EXPORT const char *qssl_dhparams_default_base64 =
73 "MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR"
74 "Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL"
75 "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC";
76
77/*!
78 Returns the default QSslDiffieHellmanParameters used by QSslSocket.
79
80 This is currently the 1024-bit MODP group from RFC 2459, also
81 known as the Second Oakley Group.
82*/
83QSslDiffieHellmanParameters QSslDiffieHellmanParameters::defaultParameters()
84{
85 QSslDiffieHellmanParameters def;
86 def.d->derData = QByteArray::fromBase64(base64: QByteArray(qssl_dhparams_default_base64));
87 return def;
88}
89
90/*!
91 Constructs an empty QSslDiffieHellmanParameters instance.
92
93 If an empty QSslDiffieHellmanParameters instance is set on a
94 QSslConfiguration object, Diffie-Hellman negotiation will
95 be disabled.
96
97 \sa isValid()
98 \sa QSslConfiguration
99*/
100QSslDiffieHellmanParameters::QSslDiffieHellmanParameters()
101 : d(new QSslDiffieHellmanParametersPrivate)
102{
103 d->ref.ref();
104}
105
106/*!
107 Constructs a QSslDiffieHellmanParameters object using
108 the byte array \a encoded in either PEM or DER form as specified by \a encoding.
109
110 Use the isValid() method on the returned object to
111 check whether the Diffie-Hellman parameters were valid and
112 loaded correctly.
113
114 \sa isValid()
115 \sa QSslConfiguration
116*/
117QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(const QByteArray &encoded, QSsl::EncodingFormat encoding)
118{
119 QSslDiffieHellmanParameters result;
120 switch (encoding) {
121 case QSsl::Der:
122 result.d->decodeDer(der: encoded);
123 break;
124 case QSsl::Pem:
125 result.d->decodePem(pem: encoded);
126 break;
127 }
128 return result;
129}
130
131/*!
132 Constructs a QSslDiffieHellmanParameters object by
133 reading from \a device in either PEM or DER form as specified by \a encoding.
134
135 Use the isValid() method on the returned object
136 to check whether the Diffie-Hellman parameters were valid
137 and loaded correctly.
138
139 In particular, if \a device is \nullptr or not open for reading, an invalid
140 object will be returned.
141
142 \sa isValid()
143 \sa QSslConfiguration
144*/
145QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(QIODevice *device, QSsl::EncodingFormat encoding)
146{
147 if (device)
148 return fromEncoded(encoded: device->readAll(), encoding);
149 else
150 return QSslDiffieHellmanParameters();
151}
152
153/*!
154 Constructs an identical copy of \a other.
155*/
156QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(const QSslDiffieHellmanParameters &other)
157 : d(other.d)
158{
159 if (d)
160 d->ref.ref();
161}
162
163/*!
164 \fn QSslDiffieHellmanParameters::QSslDiffieHellmanParameters(QSslDiffieHellmanParameters &&other)
165
166 Move-constructs from \a other.
167
168 \note The moved-from object \a other is placed in a partially-formed state, in which
169 the only valid operations are destruction and assignment of a new value.
170*/
171
172/*!
173 Destroys the QSslDiffieHellmanParameters object.
174*/
175QSslDiffieHellmanParameters::~QSslDiffieHellmanParameters()
176{
177 if (d && !d->ref.deref())
178 delete d;
179}
180
181/*!
182 Copies the contents of \a other into this QSslDiffieHellmanParameters, making the two QSslDiffieHellmanParameters
183 identical.
184
185 Returns a reference to this QSslDiffieHellmanParameters.
186*/
187QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(const QSslDiffieHellmanParameters &other)
188{
189 QSslDiffieHellmanParameters copy(other);
190 swap(other&: copy);
191 return *this;
192}
193
194/*!
195 \fn QSslDiffieHellmanParameters &QSslDiffieHellmanParameters::operator=(QSslDiffieHellmanParameters &&other)
196
197 Move-assigns \a other to this QSslDiffieHellmanParameters instance.
198
199 \note The moved-from object \a other is placed in a partially-formed state, in which
200 the only valid operations are destruction and assignment of a new value.
201*/
202
203/*!
204 \fn void QSslDiffieHellmanParameters::swap(QSslDiffieHellmanParameters &other)
205
206 Swaps this QSslDiffieHellmanParameters with \a other. This function is very fast and
207 never fails.
208*/
209
210/*!
211 Returns \c true if this is a an empty QSslDiffieHellmanParameters instance.
212
213 Setting an empty QSslDiffieHellmanParameters instance on a QSslSocket-based
214 server will disable Diffie-Hellman key exchange.
215*/
216bool QSslDiffieHellmanParameters::isEmpty() const noexcept
217{
218 return d->derData.isNull() && d->error == QSslDiffieHellmanParameters::NoError;
219}
220
221/*!
222 Returns \c true if this is a valid QSslDiffieHellmanParameters; otherwise false.
223
224 This method should be used after constructing a QSslDiffieHellmanParameters
225 object to determine its validity.
226
227 If a QSslDiffieHellmanParameters object is not valid, you can use the error()
228 method to determine what error prevented the object from being constructed.
229
230 \sa error()
231*/
232bool QSslDiffieHellmanParameters::isValid() const noexcept
233{
234 return d->error == QSslDiffieHellmanParameters::NoError;
235}
236
237/*!
238 \enum QSslDiffieHellmanParameters::Error
239
240 Describes a QSslDiffieHellmanParameters error.
241
242 \value NoError No error occurred.
243
244 \value InvalidInputDataError The given input data could not be used to
245 construct a QSslDiffieHellmanParameters
246 object.
247
248 \value UnsafeParametersError The Diffie-Hellman parameters are unsafe
249 and should not be used.
250*/
251
252/*!
253 Returns the error that caused the QSslDiffieHellmanParameters object
254 to be invalid.
255*/
256QSslDiffieHellmanParameters::Error QSslDiffieHellmanParameters::error() const noexcept
257{
258 return d->error;
259}
260
261/*!
262 Returns a human-readable description of the error that caused the
263 QSslDiffieHellmanParameters object to be invalid.
264*/
265QString QSslDiffieHellmanParameters::errorString() const noexcept
266{
267 switch (d->error) {
268 case QSslDiffieHellmanParameters::NoError:
269 return QCoreApplication::translate(context: "QSslDiffieHellmanParameter", key: "No error");
270 case QSslDiffieHellmanParameters::InvalidInputDataError:
271 return QCoreApplication::translate(context: "QSslDiffieHellmanParameter", key: "Invalid input data");
272 case QSslDiffieHellmanParameters::UnsafeParametersError:
273 return QCoreApplication::translate(context: "QSslDiffieHellmanParameter", key: "The given Diffie-Hellman parameters are deemed unsafe");
274 }
275
276 Q_UNREACHABLE();
277 return QString();
278}
279
280/*!
281 \since 5.8
282 \relates QSslDiffieHellmanParameters
283
284 Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false.
285*/
286bool operator==(const QSslDiffieHellmanParameters &lhs, const QSslDiffieHellmanParameters &rhs) noexcept
287{
288 return lhs.d->derData == rhs.d->derData;
289}
290
291#ifndef QT_NO_DEBUG_STREAM
292/*!
293 \since 5.8
294 \relates QSslDiffieHellmanParameters
295
296 Writes the set of Diffie-Hellman parameters in \a dhparam into the debug object \a debug for
297 debugging purposes.
298
299 The Diffie-Hellman parameters will be represented in Base64-encoded DER form.
300
301 \sa {Debugging Techniques}
302*/
303QDebug operator<<(QDebug debug, const QSslDiffieHellmanParameters &dhparam)
304{
305 QDebugStateSaver saver(debug);
306 debug.resetFormat().nospace();
307 debug << "QSslDiffieHellmanParameters(" << dhparam.d->derData.toBase64() << ')';
308 return debug;
309}
310#endif
311
312/*!
313 \since 5.8
314 \relates QSslDiffieHellmanParameters
315
316 Returns an hash value for \a dhparam, using \a seed to seed
317 the calculation.
318*/
319uint qHash(const QSslDiffieHellmanParameters &dhparam, uint seed) noexcept
320{
321 return qHash(key: dhparam.d->derData, seed);
322}
323
324QT_END_NAMESPACE
325

source code of qtbase/src/network/ssl/qssldiffiehellmanparameters.cpp