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