Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4
21#include "qssl_p.h"
22#include "qsslkey.h"
23#include "qsslkey_p.h"
24#include "qsslsocket.h"
25#include "qsslsocket_p.h"
26#include "qtlsbackend_p.h"
27
28#include <QtCore/qatomic.h>
29#include <QtCore/qbytearray.h>
30#include <QtCore/qiodevice.h>
31#ifndef QT_NO_DEBUG_STREAM
32#include <QtCore/qdebug.h>
33#endif
34
36
57{
58 const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
59 if (!tlsBackend)
60 return;
61 backend.reset(tlsBackend->createKey());
62 if (backend.get())
63 backend->clear(false /*not deep clear*/);
64 else
65 qCWarning(lcSsl, "Active TLS backend does not support key creation");
66}
67
72{
73 if (backend.get())
74 backend->clear(true /*deep clear*/);
75}
76
78{
79 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse()) {
80 const std::unique_ptr<QTlsPrivate::TlsKey> cryptor(tlsBackend->createKey());
81 return cryptor->decrypt(cipher, data, key, iv);
82 }
83
84 return {};
85}
86
88{
89 if (const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse()) {
90 const std::unique_ptr<QTlsPrivate::TlsKey> cryptor(tlsBackend->createKey());
91 return cryptor->encrypt(cipher, data, key, iv);
92 }
93
94 return {};
95}
96
103 : d(new QSslKeyPrivate)
104{
105}
106
118 QSsl::EncodingFormat encoding, QSsl::KeyType type, const QByteArray &passPhrase)
119 : d(new QSslKeyPrivate)
120{
121 if (auto *tlsKey = d->backend.get()) {
122 if (encoding == QSsl::Der)
123 tlsKey->decodeDer(type, algorithm, encoded, passPhrase, true /*deep clear*/);
124 else
125 tlsKey->decodePem(type, algorithm, encoded, passPhrase, true /*deep clear*/);
126 }
127}
128
140 QSsl::KeyType type, const QByteArray &passPhrase)
141 : d(new QSslKeyPrivate)
142{
144 if (device)
145 encoded = device->readAll();
146
147 if (auto *tlsKey = d->backend.get()) {
148 if (encoding == QSsl::Der)
149 tlsKey->decodeDer(type, algorithm, encoded, passPhrase, true /*deep clear*/);
150 else
151 tlsKey->decodePem(type, algorithm, encoded, passPhrase, true /*deep clear*/);
152 }
153}
154
164 : d(new QSslKeyPrivate)
165{
166 if (auto *tlsKey = d->backend.get())
167 tlsKey->fromHandle(handle, type);
168}
169
174{
175}
176
178 : d(nullptr)
179{
180 qSwap(d, other.d);
181}
182
184{
185 if (this == &other)
186 return *this;
187
188 // If no one else is referencing the key data we want to make sure
189 // before we swap the d-ptr that it is not left in memory.
190 d.reset();
191 qSwap(d, other.d);
192 return *this;
193}
194
201
209{
210 d = other.d;
211 return *this;
212}
213
227bool QSslKey::isNull() const
228{
229 if (const auto *tlsKey = d->backend.get())
230 return tlsKey->isNull();
231
232 return true;
233}
234
241{
242 d = new QSslKeyPrivate;
243}
244
249{
250 if (const auto *tlsKey = d->backend.get())
251 return tlsKey->length();
252
253 return -1;
254}
255
260{
261 if (const auto *tlsKey = d->backend.get())
262 return tlsKey->type();
263
264 return QSsl::PublicKey;
265}
266
271{
272 if (const auto *tlsKey = d->backend.get())
273 return tlsKey->algorithm();
274
275 return QSsl::Opaque;
276}
277
284QByteArray QSslKey::toDer(const QByteArray &passPhrase) const
285{
286 if (isNull() || algorithm() == QSsl::Opaque)
287 return {};
288
289 // Encrypted DER is nonsense, see QTBUG-41038.
290 if (type() == QSsl::PrivateKey && !passPhrase.isEmpty())
291 return {};
292
293 QMap<QByteArray, QByteArray> headers;
294 if (const auto *tlsKey = d->backend.get())
295 return tlsKey->derFromPem(toPem(passPhrase), &headers);
296
297 return {};
298}
299
305QByteArray QSslKey::toPem(const QByteArray &passPhrase) const
306{
307 if (const auto *tlsKey = d->backend.get())
308 return tlsKey->toPem(passPhrase);
309
310 return {};
311}
312
325{
326 if (d->backend.get())
327 return d->backend->handle();
328
329 return nullptr;
330}
331
336{
337 if (isNull())
338 return other.isNull();
339 if (other.isNull())
340 return isNull();
341 if (algorithm() != other.algorithm())
342 return false;
343 if (type() != other.type())
344 return false;
345 if (length() != other.length())
346 return false;
347 if (algorithm() == QSsl::Opaque)
348 return handle() == other.handle();
349 return toDer() == other.toDer();
350}
351
358#ifndef QT_NO_DEBUG_STREAM
360{
361 QDebugStateSaver saver(debug);
362 debug.resetFormat().nospace();
363 debug << "QSslKey("
364 << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
365 << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" :
366 (key.algorithm() == QSsl::Rsa ? "RSA" :
367 (key.algorithm() == QSsl::Dsa ? "DSA" :
368 (key.algorithm() == QSsl::Dh ? "DH" : "EC"))))
369 << ", " << key.length()
370 << ')';
371 return debug;
372}
373#endif
374
IOBluetoothDevice * device
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore \reentrant
Definition qiodevice.h:34
static Q_NETWORK_EXPORT QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv)
Definition qsslkey_p.cpp:77
static Q_NETWORK_EXPORT QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv)
Definition qsslkey_p.cpp:87
std::unique_ptr< QTlsPrivate::TlsKey > backend
Definition qsslkey_p.h:43
The QSslKey class provides an interface for private and public keys.
Definition qsslkey.h:23
bool operator==(const QSslKey &key) const
Returns true if this key is equal to other; otherwise returns false.
int length() const
Returns the length of the key in bits, or -1 if the key is null.
~QSslKey()
Destroys the QSslKey object.
QSsl::KeyAlgorithm algorithm() const
Returns the key algorithm.
void clear()
Clears the contents of this key, making it a null key.
QByteArray toDer(const QByteArray &passPhrase=QByteArray()) const
Returns the key in DER encoding.
QSslKey()
Constructs a null key.
QByteArray toPem(const QByteArray &passPhrase=QByteArray()) const
Returns the key in PEM encoding.
Qt::HANDLE handle() const
Returns a pointer to the native key handle, if there is one, else \nullptr.
QSslKey & operator=(QSslKey &&other) noexcept
bool isNull() const
Returns true if this is a null key; otherwise false.
QSsl::KeyType type() const
Returns the type of the key (i.e., PublicKey or PrivateKey).
static QTlsBackend * tlsBackendInUse()
KeyType
Describes the two types of keys QSslKey supports.
Definition qssl.h:22
@ PublicKey
Definition qssl.h:24
@ PrivateKey
Definition qssl.h:23
KeyAlgorithm
Describes the different key algorithms supported by QSslKey.
Definition qssl.h:34
@ Rsa
Definition qssl.h:36
@ Opaque
Definition qssl.h:35
@ Dsa
Definition qssl.h:37
@ Dh
Definition qssl.h:39
EncodingFormat
Describes supported encoding formats for certificates and keys.
Definition qssl.h:28
@ Der
Definition qssl.h:30
Combined button and popup list for selecting options.
void * HANDLE
#define qCWarning(category,...)
GLuint64 GLenum void * handle
GLuint64 key
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
QDebug operator<<(QDebug debug, const QSslKey &key)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Definition qswap.h:20
QSharedPointer< T > other(t)
[5]