Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qsslkey_p.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 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
6
/*!
7
\class QSslKey
8
\brief The QSslKey class provides an interface for private and public keys.
9
\since 4.3
10
11
\reentrant
12
\ingroup network
13
\ingroup ssl
14
\ingroup shared
15
\inmodule QtNetwork
16
17
QSslKey provides a simple API for managing keys.
18
19
\sa QSslSocket, QSslCertificate, QSslCipher
20
*/
21
22
#
include
"qssl_p.h"
23
#
include
"qsslkey.h"
24
#
include
"qsslkey_p.h"
25
#
include
"qsslsocket.h"
26
#
include
"qsslsocket_p.h"
27
#
include
"qtlsbackend_p.h"
28
29
#
include
<
QtCore
/
qatomic
.
h
>
30
#
include
<
QtCore
/
qbytearray
.
h
>
31
#
include
<
QtCore
/
qiodevice
.
h
>
32
#
ifndef
QT_NO_DEBUG_STREAM
33
#
include
<
QtCore
/
qdebug
.
h
>
34
#
endif
35
36
QT_BEGIN_NAMESPACE
37
38
/*!
39
\fn void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhrase,
40
bool deepClear)
41
\internal
42
43
Allocates a new rsa or dsa struct and decodes \a pem into it
44
according to the current algorithm and type.
45
46
If \a deepClear is true, the rsa/dsa struct is freed if it is was
47
already allocated, otherwise we "leak" memory (which is exactly
48
what we want for copy construction).
49
50
If \a passPhrase is non-empty, it will be used for decrypting
51
\a pem.
52
*/
53
54
/*!
55
\internal
56
*/
57
QSslKeyPrivate::QSslKeyPrivate()
58
{
59
const
auto
*tlsBackend = QSslSocketPrivate::tlsBackendInUse();
60
if
(!tlsBackend)
61
return
;
62
backend.reset(tlsBackend->createKey());
63
if
(backend.get())
64
backend->clear(
false
/*not deep clear*/
);
65
else
66
qCWarning(lcSsl,
"Active TLS backend does not support key creation"
);
67
}
68
69
/*!
70
\internal
71
*/
72
QSslKeyPrivate
::~
QSslKeyPrivate
()
73
{
74
if
(backend.get())
75
backend->clear(
true
/*deep clear*/
);
76
}
77
78
QByteArray
QSslKeyPrivate
::decrypt(Cipher cipher,
const
QByteArray
&data,
const
QByteArray
&key,
const
QByteArray
&iv)
79
{
80
if
(
const
auto
*tlsBackend = QSslSocketPrivate::tlsBackendInUse()) {
81
const
std::unique_ptr<QTlsPrivate::TlsKey> cryptor(tlsBackend->createKey());
82
return
cryptor->decrypt(cipher, data, key, iv);
83
}
84
85
return
{};
86
}
87
88
QByteArray
QSslKeyPrivate
::encrypt(Cipher cipher,
const
QByteArray
&data,
const
QByteArray
&key,
const
QByteArray
&iv)
89
{
90
if
(
const
auto
*tlsBackend = QSslSocketPrivate::tlsBackendInUse()) {
91
const
std::unique_ptr<QTlsPrivate::TlsKey> cryptor(tlsBackend->createKey());
92
return
cryptor->encrypt(cipher, data, key, iv);
93
}
94
95
return
{};
96
}
97
98
/*!
99
Constructs a null key.
100
101
\sa isNull()
102
*/
103
QSslKey::QSslKey()
104
: d(
new
QSslKeyPrivate)
105
{
106
}
107
108
/*!
109
Constructs a QSslKey by decoding the string in the byte array
110
\a encoded using a specified \a algorithm and \a encoding format.
111
\a type specifies whether the key is public or private.
112
113
If the key is encrypted then \a passPhrase is used to decrypt it.
114
115
After construction, use isNull() to check if \a encoded contained
116
a valid key.
117
*/
118
QSslKey::QSslKey(
const
QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
119
QSsl::EncodingFormat encoding, QSsl::KeyType type,
const
QByteArray &passPhrase)
120
: d(
new
QSslKeyPrivate)
121
{
122
if
(
auto
*tlsKey = d->backend.get()) {
123
if
(encoding == QSsl::Der)
124
tlsKey->decodeDer(type, algorithm, encoded, passPhrase,
true
/*deep clear*/
);
125
else
126
tlsKey->decodePem(type, algorithm, encoded, passPhrase,
true
/*deep clear*/
);
127
}
128
}
129
130
/*!
131
Constructs a QSslKey by reading and decoding data from a
132
\a device using a specified \a algorithm and \a encoding format.
133
\a type specifies whether the key is public or private.
134
135
If the key is encrypted then \a passPhrase is used to decrypt it.
136
137
After construction, use isNull() to check if \a device provided
138
a valid key.
139
*/
140
QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat encoding,
141
QSsl::KeyType type,
const
QByteArray &passPhrase)
142
: d(
new
QSslKeyPrivate)
143
{
144
QByteArray encoded;
145
if
(device)
146
encoded = device->readAll();
147
148
if
(
auto
*tlsKey = d->backend.get()) {
149
if
(encoding == QSsl::Der)
150
tlsKey->decodeDer(type, algorithm, encoded, passPhrase,
true
/*deep clear*/
);
151
else
152
tlsKey->decodePem(type, algorithm, encoded, passPhrase,
true
/*deep clear*/
);
153
}
154
}
155
156
/*!
157
\since 5.0
158
Constructs a QSslKey from a valid native key \a handle.
159
\a type specifies whether the key is public or private.
160
161
QSslKey will take ownership for this key and you must not
162
free the key using the native library.
163
*/
164
QSslKey::QSslKey(Qt::HANDLE handle, QSsl::KeyType type)
165
: d(
new
QSslKeyPrivate)
166
{
167
if
(
auto
*tlsKey = d->backend.get())
168
tlsKey->fromHandle(handle, type);
169
}
170
171
/*!
172
Constructs an identical copy of \a other.
173
*/
174
QSslKey::QSslKey(
const
QSslKey &other) : d(other.d)
175
{
176
}
177
178
QSslKey::QSslKey(QSslKey &&other)
noexcept
179
: d(
nullptr
)
180
{
181
qSwap(d, other.d);
182
}
183
184
QSslKey &QSslKey::operator=(QSslKey &&other)
noexcept
185
{
186
if
(
this
== &other)
187
return
*
this
;
188
189
// If no one else is referencing the key data we want to make sure
190
// before we swap the d-ptr that it is not left in memory.
191
d.reset();
192
qSwap(d, other.d);
193
return
*
this
;
194
}
195
196
/*!
197
Destroys the QSslKey object.
198
*/
199
QSslKey::~QSslKey()
200
{
201
}
202
203
/*!
204
Copies the contents of \a other into this key, making the two keys
205
identical.
206
207
Returns a reference to this QSslKey.
208
*/
209
QSslKey &QSslKey::operator=(
const
QSslKey &other)
210
{
211
d = other.d;
212
return
*
this
;
213
}
214
215
/*!
216
\fn void QSslKey::swap(QSslKey &other)
217
\since 5.0
218
\memberswap{ssl key}
219
*/
220
221
/*!
222
Returns \c true if this is a null key; otherwise false.
223
224
\sa clear()
225
*/
226
bool
QSslKey::isNull()
const
227
{
228
if
(
const
auto
*tlsKey = d->backend.get())
229
return
tlsKey->isNull();
230
231
return
true
;
232
}
233
234
/*!
235
Clears the contents of this key, making it a null key.
236
237
\sa isNull()
238
*/
239
void
QSslKey::clear()
240
{
241
d =
new
QSslKeyPrivate;
242
}
243
244
/*!
245
Returns the length of the key in bits, or -1 if the key is null.
246
*/
247
int
QSslKey::length()
const
248
{
249
if
(
const
auto
*tlsKey = d->backend.get())
250
return
tlsKey->length();
251
252
return
-1;
253
}
254
255
/*!
256
Returns the type of the key (i.e., PublicKey or PrivateKey).
257
*/
258
QSsl::KeyType QSslKey::type()
const
259
{
260
if
(
const
auto
*tlsKey = d->backend.get())
261
return
tlsKey->type();
262
263
return
QSsl::PublicKey;
264
}
265
266
/*!
267
Returns the key algorithm.
268
*/
269
QSsl::KeyAlgorithm QSslKey::algorithm()
const
270
{
271
if
(
const
auto
*tlsKey = d->backend.get())
272
return
tlsKey->algorithm();
273
274
return
QSsl::Opaque;
275
}
276
277
/*!
278
Returns the key in DER encoding.
279
280
The \a passPhrase argument should be omitted as DER cannot be
281
encrypted. It will be removed in a future version of Qt.
282
*/
283
QByteArray QSslKey::toDer(
const
QByteArray &passPhrase)
const
284
{
285
if
(isNull() || algorithm() == QSsl::Opaque)
286
return
{};
287
288
// Encrypted DER is nonsense, see QTBUG-41038.
289
if
(type() == QSsl::PrivateKey && !passPhrase.isEmpty())
290
return
{};
291
292
QMap<QByteArray, QByteArray> headers;
293
if
(
const
auto
*tlsKey = d->backend.get())
294
return
tlsKey->derFromPem(toPem(passPhrase), &headers);
295
296
return
{};
297
}
298
299
/*!
300
Returns the key in PEM encoding. The result is encrypted with
301
\a passPhrase if the key is a private key and \a passPhrase is
302
non-empty.
303
*/
304
QByteArray QSslKey::toPem(
const
QByteArray &passPhrase)
const
305
{
306
if
(
const
auto
*tlsKey = d->backend.get())
307
return
tlsKey->toPem(passPhrase);
308
309
return
{};
310
}
311
312
/*!
313
Returns a pointer to the native key handle, if there is
314
one, else \nullptr.
315
316
You can use this handle together with the native API to access
317
extended information about the key.
318
319
\warning Use of this function has a high probability of being
320
non-portable, and its return value may vary across platforms, and
321
between minor Qt releases.
322
*/
323
Qt::HANDLE QSslKey::handle()
const
324
{
325
if
(d->backend.get())
326
return
d->backend->handle();
327
328
return
nullptr
;
329
}
330
331
/*!
332
Returns \c true if this key is equal to \a other; otherwise returns \c false.
333
*/
334
bool
QSslKey::operator==(
const
QSslKey &other)
const
335
{
336
if
(isNull())
337
return
other.isNull();
338
if
(other.isNull())
339
return
isNull();
340
if
(algorithm() != other.algorithm())
341
return
false
;
342
if
(type() != other.type())
343
return
false
;
344
if
(length() != other.length())
345
return
false
;
346
if
(algorithm() == QSsl::Opaque)
347
return
handle() == other.handle();
348
return
toDer() == other.toDer();
349
}
350
351
/*! \fn bool QSslKey::operator!=(const QSslKey &other) const
352
353
Returns \c true if this key is not equal to key \a other; otherwise
354
returns \c false.
355
*/
356
357
#
ifndef
QT_NO_DEBUG_STREAM
358
QDebug operator<<(QDebug debug,
const
QSslKey &key)
359
{
360
QDebugStateSaver saver(debug);
361
debug.resetFormat().nospace();
362
debug <<
"QSslKey("
363
<< (key.type() == QSsl::PublicKey ?
"PublicKey"
:
"PrivateKey"
)
364
<<
", "
<< (key.algorithm() == QSsl::Opaque ?
"OPAQUE"
:
365
(key.algorithm() == QSsl::Rsa ?
"RSA"
:
366
(key.algorithm() == QSsl::Dsa ?
"DSA"
:
367
(key.algorithm() == QSsl::Dh ?
"DH"
:
368
(key.algorithm() == QSsl::Ec ?
"EC"
:
"ML-DSA"
)))))
369
<<
", "
<< key.length()
370
<<
')'
;
371
return
debug;
372
}
373
#
endif
374
375
QT_END_NAMESPACE
QByteArray::FromBase64Result
\inmodule QtCore
Definition
qbytearray.h:824
QSslKeyPrivate
Definition
qsslkey_p.h:34
QSslKeyPrivate::~QSslKeyPrivate
~QSslKeyPrivate()
Definition
qsslkey_p.cpp:72
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtbase
src
network
ssl
qsslkey_p.cpp
Generated on
for Qt by
1.18.0