1 | // Copyright (C) 2019 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include "qcoapsecurityconfiguration.h" |
5 | |
6 | #include <QtCore/QByteArray> |
7 | #include <QtCore/QIODevice> |
8 | #include <QtCore/QList> |
9 | #include <QtNetwork/QSslCertificate> |
10 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | class QCoapPrivateKeyPrivate : public QSharedData |
14 | { |
15 | public: |
16 | QByteArray key; |
17 | Qt::HANDLE opaqueKey = nullptr; |
18 | QSsl::KeyAlgorithm algorithm = QSsl::Opaque; |
19 | QSsl::EncodingFormat encodingFormat; |
20 | QByteArray passPhrase; |
21 | }; |
22 | |
23 | class QCoapSecurityConfigurationPrivate : public QSharedData |
24 | { |
25 | public: |
26 | QByteArray identity; |
27 | QByteArray preSharedKey; |
28 | QString defaultCipherString; |
29 | QList<QSslCertificate> caCertificates; |
30 | QList<QSslCertificate> localCertificateChain; |
31 | QCoapPrivateKey privateKey; |
32 | }; |
33 | |
34 | /*! |
35 | \class QCoapPrivateKey |
36 | \inmodule QtCoap |
37 | |
38 | \brief The QCoapPrivateKey class provides an interface for managing |
39 | CoAP security keys. |
40 | |
41 | A QCoapPrivateKey packages a private key used in negotiating CoAP connections |
42 | securely. It holds the information required for authentication using |
43 | \c pre-shared keys and X.509 certificates. |
44 | */ |
45 | |
46 | /*! |
47 | \fn void QCoapPrivateKey::swap(QCoapPrivateKey &other) |
48 | |
49 | Swaps this private key with \a other. This operation is very fast and never fails. |
50 | */ |
51 | |
52 | /*! |
53 | Constructs an empty instance of QCoapPrivateKey. |
54 | */ |
55 | QCoapPrivateKey::QCoapPrivateKey() |
56 | : d(new QCoapPrivateKeyPrivate) |
57 | { |
58 | } |
59 | |
60 | /*! |
61 | Constructs a QCoapPrivateKey from the byte array \a key using |
62 | the specified \a algorithm and encoding \a format. |
63 | |
64 | If the key is encrypted then \a passPhrase is required to decrypt it. |
65 | */ |
66 | QCoapPrivateKey::QCoapPrivateKey(const QByteArray &key, QSsl::KeyAlgorithm algorithm, |
67 | QSsl::EncodingFormat format, const QByteArray &passPhrase) |
68 | : d(new QCoapPrivateKeyPrivate) |
69 | { |
70 | d->key = key; |
71 | d->opaqueKey = nullptr; |
72 | d->algorithm = algorithm; |
73 | d->encodingFormat = format; |
74 | d->passPhrase = passPhrase; |
75 | } |
76 | |
77 | /*! |
78 | Constructs a QCoapPrivateKey from a native key \a handle. |
79 | */ |
80 | QCoapPrivateKey::QCoapPrivateKey(const Qt::HANDLE &handle) |
81 | : d(new QCoapPrivateKeyPrivate) |
82 | { |
83 | d->opaqueKey = handle; |
84 | d->algorithm = QSsl::Opaque; |
85 | } |
86 | |
87 | /*! |
88 | Copies the contents of \a other into this key, making the two keys |
89 | identical. |
90 | */ |
91 | QCoapPrivateKey::QCoapPrivateKey(const QCoapPrivateKey &other) |
92 | : d(other.d) |
93 | { |
94 | } |
95 | |
96 | /*! |
97 | Move-constructs a QCoapPrivateKey, making it point to the same |
98 | object as \a other was pointing to. |
99 | */ |
100 | QCoapPrivateKey::QCoapPrivateKey(QCoapPrivateKey &&other) noexcept |
101 | : d(other.d) |
102 | { |
103 | other.d = nullptr; |
104 | } |
105 | |
106 | /*! |
107 | Releases any resources held by QCoapPrivateKey. |
108 | */ |
109 | QCoapPrivateKey::~QCoapPrivateKey() |
110 | { |
111 | } |
112 | |
113 | /*! |
114 | Copies the contents of \a other into this key, making the two keys |
115 | identical. |
116 | |
117 | Returns a reference to this QCoapPrivateKey. |
118 | */ |
119 | QCoapPrivateKey &QCoapPrivateKey::operator=(const QCoapPrivateKey &other) |
120 | { |
121 | d = other.d; |
122 | return *this; |
123 | } |
124 | |
125 | /*! |
126 | Returns \c true if the private key is null, returns \c false otherwise. |
127 | */ |
128 | bool QCoapPrivateKey::isNull() const |
129 | { |
130 | return d->algorithm == QSsl::Opaque ? !d->opaqueKey : d->key.isEmpty(); |
131 | } |
132 | |
133 | /*! |
134 | Returns the encoded private key. |
135 | */ |
136 | QByteArray QCoapPrivateKey::key() const |
137 | { |
138 | return d->key; |
139 | } |
140 | |
141 | /*! |
142 | Returns a pointer to the native key handle. |
143 | */ |
144 | Qt::HANDLE QCoapPrivateKey::handle() const |
145 | { |
146 | return d->opaqueKey; |
147 | } |
148 | |
149 | /*! |
150 | Returns the key algorithm. |
151 | */ |
152 | QSsl::KeyAlgorithm QCoapPrivateKey::algorithm() const |
153 | { |
154 | return d->algorithm; |
155 | } |
156 | |
157 | /*! |
158 | Returns the encoding format of the key. |
159 | */ |
160 | QSsl::EncodingFormat QCoapPrivateKey::encodingFormat() const |
161 | { |
162 | return d->encodingFormat; |
163 | } |
164 | |
165 | /*! |
166 | Returns the passphrase for the key. |
167 | */ |
168 | QByteArray QCoapPrivateKey::passPhrase() const |
169 | { |
170 | return d->passPhrase; |
171 | } |
172 | |
173 | /*! |
174 | \class QCoapSecurityConfiguration |
175 | \inmodule QtCoap |
176 | |
177 | \brief The QCoapSecurityConfiguration class holds configuration |
178 | options during the authentication process. |
179 | |
180 | It holds information such as client identity, pre shared key, information |
181 | about certificates, and so on. |
182 | */ |
183 | |
184 | |
185 | /*! |
186 | \fn void QCoapSecurityConfiguration::swap(QCoapSecurityConfiguration &other) |
187 | |
188 | Swaps this security configuration with \a other. This operation is very fast |
189 | and never fails. |
190 | */ |
191 | |
192 | /*! |
193 | Constructs a new QCoapSecurityConfiguration. |
194 | */ |
195 | QCoapSecurityConfiguration::QCoapSecurityConfiguration() |
196 | : d(new QCoapSecurityConfigurationPrivate) |
197 | { |
198 | } |
199 | |
200 | /*! |
201 | Copies the configuration and state of \a other. |
202 | */ |
203 | QCoapSecurityConfiguration::QCoapSecurityConfiguration(const QCoapSecurityConfiguration &other) |
204 | : d(other.d) |
205 | { |
206 | } |
207 | |
208 | /*! |
209 | Move-constructs a QCoapSecurityConfiguration, making it point to the same |
210 | object as \a other was pointing to. |
211 | */ |
212 | QCoapSecurityConfiguration::QCoapSecurityConfiguration( |
213 | QCoapSecurityConfiguration &&other) noexcept |
214 | : d(other.d) |
215 | { |
216 | other.d = nullptr; |
217 | } |
218 | |
219 | /*! |
220 | Copies the configuration and state of \a other. |
221 | */ |
222 | QCoapSecurityConfiguration &QCoapSecurityConfiguration::operator=( |
223 | const QCoapSecurityConfiguration &other) |
224 | { |
225 | d = other.d; |
226 | return *this; |
227 | } |
228 | |
229 | /*! |
230 | Releases any resources held by QCoapSecurityConfiguration. |
231 | */ |
232 | QCoapSecurityConfiguration::~QCoapSecurityConfiguration() |
233 | { |
234 | } |
235 | |
236 | /*! |
237 | Sets the PSK client identity (to be advised to the server) to \a identity. |
238 | |
239 | \sa preSharedKeyIdentity() |
240 | */ |
241 | void QCoapSecurityConfiguration::setPreSharedKeyIdentity(const QByteArray &identity) |
242 | { |
243 | d->identity = identity; |
244 | } |
245 | |
246 | /*! |
247 | Returns the PSK client identity. |
248 | |
249 | \sa setPreSharedKeyIdentity() |
250 | */ |
251 | QByteArray QCoapSecurityConfiguration::preSharedKeyIdentity() const |
252 | { |
253 | return d->identity; |
254 | } |
255 | |
256 | /*! |
257 | Sets the pre shared key to \a preSharedKey. |
258 | |
259 | \sa preSharedKey() |
260 | */ |
261 | void QCoapSecurityConfiguration::setPreSharedKey(const QByteArray &preSharedKey) |
262 | { |
263 | d->preSharedKey = preSharedKey; |
264 | } |
265 | |
266 | /*! |
267 | Returns the pre shared key. |
268 | |
269 | \sa setPreSharedKey() |
270 | */ |
271 | QByteArray QCoapSecurityConfiguration::preSharedKey() const |
272 | { |
273 | return d->preSharedKey; |
274 | } |
275 | |
276 | /*! |
277 | Sets the SSL cipher string to \a cipherString. |
278 | |
279 | The security back-end (for example OpenSSL) might not include ciphers required |
280 | for \l{https://tools.ietf.org/html/rfc7252#section-9}{RFC 7252} by default. |
281 | This method specifies which ciphers the back-end should use. |
282 | For example to enable CCM ciphers required by RFC, "AESCCM" can be passed |
283 | as \a cipherString. |
284 | |
285 | See the \l{https://www.openssl.org/docs/manmaster/man1/ciphers.html#CIPHER-STRINGS} |
286 | {OpenSSL docs} for more information about cipher strings. |
287 | |
288 | \sa defaultCipherString() |
289 | */ |
290 | void QCoapSecurityConfiguration::setDefaultCipherString(const QString &cipherString) |
291 | { |
292 | d->defaultCipherString = cipherString; |
293 | } |
294 | |
295 | /*! |
296 | Returns the default cipher string. |
297 | |
298 | \sa setDefaultCipherString() |
299 | */ |
300 | QString QCoapSecurityConfiguration::defaultCipherString() const |
301 | { |
302 | return d->defaultCipherString; |
303 | } |
304 | |
305 | /*! |
306 | Sets \a certificates as the certificate authority database for the connection. |
307 | |
308 | \sa caCertificates() |
309 | */ |
310 | void QCoapSecurityConfiguration::setCaCertificates(const QList<QSslCertificate> &certificates) |
311 | { |
312 | d->caCertificates = certificates; |
313 | } |
314 | |
315 | /*! |
316 | Returns this connection's certificate authority certificate database. |
317 | |
318 | \sa setCaCertificates() |
319 | */ |
320 | QList<QSslCertificate> QCoapSecurityConfiguration::caCertificates() const |
321 | { |
322 | return d->caCertificates; |
323 | } |
324 | |
325 | /*! |
326 | Sets \a localChain as the certificate chain to present to the peer |
327 | during the handshake. |
328 | |
329 | \sa localCertificateChain() |
330 | */ |
331 | void QCoapSecurityConfiguration::setLocalCertificateChain(const QList<QSslCertificate> &localChain) |
332 | { |
333 | d->localCertificateChain = localChain; |
334 | } |
335 | |
336 | /*! |
337 | Returns the certificate chain to be presented to the peer during the handshake. |
338 | |
339 | \sa setLocalCertificateChain() |
340 | */ |
341 | QList<QSslCertificate> QCoapSecurityConfiguration::localCertificateChain() const |
342 | { |
343 | return d->localCertificateChain; |
344 | } |
345 | |
346 | /*! |
347 | Sets the connection's private key to \a key. |
348 | |
349 | \sa privateKey(), setLocalCertificateChain() |
350 | */ |
351 | void QCoapSecurityConfiguration::setPrivateKey(const QCoapPrivateKey &key) |
352 | { |
353 | d->privateKey = key; |
354 | } |
355 | |
356 | /*! |
357 | Returns the private key assigned to the connection. |
358 | |
359 | \sa setPrivateKey(), localCertificateChain() |
360 | */ |
361 | QCoapPrivateKey QCoapSecurityConfiguration::privateKey() const |
362 | { |
363 | return d->privateKey; |
364 | } |
365 | |
366 | QT_END_NAMESPACE |
367 | |