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
qsslkeyingmaterial.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Governikus GmbH & Co. KG.
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
6
7#ifndef QT_NO_DEBUG_STREAM
8#include <QtCore/qdebug.h>
9#endif
10#include <QtCore/qhashfunctions.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \class QSslKeyingMaterial
16 \since 6.12
17
18 \brief Describes exported keying material derived from a TLS session.
19
20 \reentrant
21 \ingroup network
22 \ingroup ssl
23 \inmodule QtNetwork
24 \compares equality
25
26 QSslKeyingMaterial represents a request for keying material derived
27 from an established TLS connection using the TLS exporter mechanism.
28
29 The exporter mechanism is defined in RFC 5705 for TLS 1.2 and earlier
30 and in RFC 8446 for TLS 1.3. It allows applications to derive
31 cryptographically separate keying material from the TLS session
32 without exposing the session's traffic keys.
33
34 Each QSslKeyingMaterial object specifies:
35 \list
36 \li an exporter label identifying the purpose of the derived
37 keying material
38 \li an optional context value binding the keying material to
39 application-specific data
40 \li the desired size of the exported keying material
41 \endlist
42
43 The actual keying material is derived by the TLS backend after a
44 successful handshake and can be retrieved via value().
45
46 QSslKeyingMaterial objects are typically configured via
47 QSslConfiguration::setKeyingMaterial() before initiating a TLS
48 connection.
49
50 Example: Deterministic export on client and server
51 \code
52 // Both client and server configure the same label and optional context
53 QSslKeyingMaterial keying("session-label", 32, "app-specific-context");
54
55 // After the TLS handshake completes get data from QSslConfiguration.
56 QByteArray derived = sslConfiguration().keyingMaterial(keying)->value();
57
58 // Both client and server will obtain the same 'derived' bytes
59 // even though they each performed the derivation independently.
60 qDebug() << "Derived keying material:" << derived;
61 \endcode
62*/
63
64/*!
65 Default-constructs an instance of QSslKeyingMaterial.
66
67 A default instance is never valid.
68
69 \sa isValid()
70*/
71
72QSslKeyingMaterial::QSslKeyingMaterial()
73 = default;
74
75/*!
76 \fn explicit QSslKeyingMaterial::QSslKeyingMaterial(const QByteArray &label, qsizetype size)
77 \fn explicit QSslKeyingMaterial::QSslKeyingMaterial(const QByteArray &label, qsizetype size, const QByteArray &context)
78
79 Constructs a QSslKeyingMaterial object with the given exporter
80 \a label, output \a size, and optional \a context.
81
82 The \a label identifies the purpose of the exported keying material
83 and must be non-empty. The \a size specifies the number of bytes
84 to be derived from the TLS exporter.
85
86 The optional \a context is application-defined data that is mixed
87 into the key derivation process to provide domain separation.
88
89 The keying material itself is not generated until a TLS handshake
90 has completed successfully.
91
92 \note Under TLS 1.2 (RFC 5705), a null context and an empty (non-null)
93 context produce different keying material: the context length field is
94 omitted entirely when no context is present, yielding a different PRF
95 input. Under TLS 1.3 (RFC 8446), an absent context and an empty context
96 are defined to be equivalent and produce the same keying material.
97 Use \l{QByteArray::isNull()} to distinguish them.
98
99 \sa isValid(), label(), context(), value()
100*/
101
102QSslKeyingMaterial::QSslKeyingMaterial(const QByteArray &label, qsizetype size)
103 : m_label(label),
104 m_requestedSize(size)
105{
106}
107
108QSslKeyingMaterial::QSslKeyingMaterial(const QByteArray &label, qsizetype size, const QByteArray &context)
109 : m_label(label),
110 m_context(context),
111 m_requestedSize(size)
112{
113}
114
115QSslKeyingMaterial::QSslKeyingMaterial(const QSslKeyingMaterial &other)
116 = default;
117
119 = default;
120
121QSslKeyingMaterial::~QSslKeyingMaterial()
122 = default;
123
124/*!
125 Returns true if this QSslKeyingMaterial object describes a valid
126 exporter request.
127
128 A QSslKeyingMaterial object is considered valid if it has a
129 non-empty exporter label and a positive output size.
130
131 \sa label(), value()
132*/
133
134bool QSslKeyingMaterial::isValid() const noexcept
135{
136 return !m_label.isEmpty() && requestedSize() > 0;
137}
138
139/*!
140 \fn QByteArray QSslKeyingMaterial::label() const
141
142 Returns the exporter label used for deriving the keying material.
143
144 The label identifies the purpose of the exported keying material
145 and is included verbatim in the TLS exporter derivation.
146
147 \sa context(), value()
148*/
149
150/*!
151 \fn QByteArray QSslKeyingMaterial::context() const
152
153 Returns the optional context value used for deriving the keying material.
154
155 The context value binds the exported keying material to
156 application-specific data and helps prevent accidental reuse of
157 identical keys across different purposes.
158
159 If no context was specified, a null/empty QByteArray is returned (see
160 \l{QSslKeyingMaterial::QSslKeyingMaterial()}).
161
162 \sa label(), value()
163*/
164
165/*!
166 \fn QByteArray QSslKeyingMaterial::value() const
167
168 Returns the exported keying material.
169
170 The returned QByteArray contains the keying material derived from
171 the TLS session using the configured exporter label and context.
172
173 If the TLS handshake has not completed successfully or if the TLS
174 backend does not support key exporters, this function returns an
175 empty value.
176
177 \note The contents of the returned keying material are
178 security-sensitive and must be handled with care.
179
180 \sa label(), context(), requestedSize()
181*/
182
183/*!
184 \fn qsizetype QSslKeyingMaterial::requestedSize() const noexcept
185
186 The desired size of the keying material.
187
188 The desired size is the number of bytes the handshake protocol
189 is asked to generate for the purpose described by the \l label()
190 and \l context() of the requested keying material.
191
192 \sa value()
193*/
194
195/*!
196 \fn void QSslKeyingMaterial::swap(QSslKeyingMaterial &other) noexcept
197 \memberswap{keying material}
198*/
199
200/*!
201 \fn size_t qHash(const QSslKeyingMaterial &key) noexcept
202 \fn size_t qHash(const QSslKeyingMaterial &key, size_t seed) noexcept
203 \qhashold{QHash}
204*/
205size_t qHash(const QSslKeyingMaterial &material, size_t seed) noexcept
206{
207 return qHashMulti(seed, material.m_label, material.m_context, material.m_value,
208 material.m_requestedSize);
209}
210
211// friend
212bool comparesEqual(const QSslKeyingMaterial &lhs, const QSslKeyingMaterial &rhs) noexcept
213{
214 return lhs.m_requestedSize == rhs.m_requestedSize
215 && lhs.m_label == rhs.m_label
216 && lhs.m_context == rhs.m_context
217 && lhs.m_value == rhs.m_value;
218}
219
220#ifndef QT_NO_DEBUG_STREAM
221/*!
222 \relates QSslKeyingMaterial
223
224 Writes a textual representation of the keying material \a keying
225 to the debug object \a debug.
226
227 \sa {Debugging Techniques}
228*/
229QDebug operator<<(QDebug debug, const QSslKeyingMaterial &keying)
230{
231 QDebugStateSaver saver(debug);
232 debug.resetFormat().nospace();
233 debug << "QSslKeyingMaterial("
234 << keying.label() << ',' << keying.context()
235 << ", requested size: " << keying.requestedSize()
236 << ", actual size: " << keying.value().size() << ')';
237 return debug;
238}
239#endif
240
241QT_END_NAMESPACE
Describes exported keying material derived from a TLS session.
Q_NETWORK_EXPORT bool isValid() const noexcept
Returns true if this QSslKeyingMaterial object describes a valid exporter request.
size_t qHash(const QSslKeyingMaterial &material, size_t seed) noexcept
\qhashold{QHash}
bool comparesEqual(const QSslKeyingMaterial &lhs, const QSslKeyingMaterial &rhs) noexcept