14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
244
245
248
249
250
251
252
253
254
255
256
257
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
306 return QDtls::tr(
"Multicast and broadcast addresses are not supported");
310
311
312
313
314
315
316
317
318QDtlsClientVerifier::GeneratorParameters::GeneratorParameters()
323
324
325
326
327
328
329
330QDtlsClientVerifier::GeneratorParameters::GeneratorParameters(QCryptographicHash::Algorithm algorithm,
const QByteArray &secret)
331 : hash(algorithm), secret(secret)
337 const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
339 qCWarning(lcSsl,
"No TLS backend is available, cannot verify DTLS client");
342 backend.reset(tlsBackend->createDtlsCookieVerifier());
344 qCWarning(lcSsl) <<
"The backend" << tlsBackend->backendName() <<
"does not support DTLS cookies";
350
351
352
353QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent)
354 : QObject(*
new QDtlsClientVerifierPrivate, parent)
356 Q_D(QDtlsClientVerifier);
358 if (
auto *backend = d->backend.get()) {
362 auto conf = QSslConfiguration::defaultDtlsConfiguration();
363 conf.setPeerVerifyMode(QSslSocket::VerifyNone);
364 backend->setConfiguration(conf);
369
370
371QDtlsClientVerifier::~QDtlsClientVerifier()
376
377
378
379
380
381
382
383
384
385
386bool QDtlsClientVerifier::setCookieGeneratorParameters(
const GeneratorParameters ¶ms)
388 Q_D(QDtlsClientVerifier);
389 if (
auto *backend = d->backend.get())
390 return backend->setCookieGeneratorParameters(params);
396
397
398
399
400
401
402
403
404
405QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters()
const
407 Q_D(
const QDtlsClientVerifier);
409 if (
const auto *backend = d->backend.get())
410 return backend->cookieGeneratorParameters();
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket,
const QByteArray &dgram,
431 const QHostAddress &address, quint16 port)
433 Q_D(QDtlsClientVerifier);
435 auto *backend = d->backend.get();
439 if (!socket || address.isNull() || !dgram.size()) {
440 backend->setDtlsError(QDtlsError::InvalidInputParameters,
441 tr(
"A valid UDP socket, non-empty datagram, and valid address/port were expected"));
445 if (address.isBroadcast() || address.isMulticast()) {
446 backend->setDtlsError(QDtlsError::InvalidInputParameters,
447 msgUnsupportedMulticastAddress());
451 return backend->verifyClient(socket, dgram, address, port);
455
456
457
458
459
460QByteArray QDtlsClientVerifier::verifiedHello()
const
462 Q_D(
const QDtlsClientVerifier);
464 if (
const auto *backend = d->backend.get())
465 return backend->verifiedHello();
471
472
473
474
475QDtlsError QDtlsClientVerifier::dtlsError()
const
477 Q_D(
const QDtlsClientVerifier);
479 if (
const auto *backend = d->backend.get())
480 return backend->error();
482 return QDtlsError::TlsInitializationError;
486
487
488
489
490QString QDtlsClientVerifier::dtlsErrorString()
const
492 Q_D(
const QDtlsClientVerifier);
494 if (
const auto *backend = d->backend.get())
495 return backend->errorString();
497 return QStringLiteral(
"No TLS backend is available, no client verification");
504
505
506
507
508
509
510QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent)
511 : QObject(*
new QDtlsPrivate, parent)
514 const auto *tlsBackend = QSslSocketPrivate::tlsBackendInUse();
516 qCWarning(lcSsl,
"No TLS backend found, QDtls is unsupported");
519 d->backend.reset(tlsBackend->createDtlsCryptograph(
this, mode));
520 if (!d->backend.get()) {
521 qCWarning(lcSsl) <<
"TLS backend" << tlsBackend->backendName()
522 <<
"does not support the protocol DTLS";
524 setDtlsConfiguration(QSslConfiguration::defaultDtlsConfiguration());
528
529
535
536
537
538
539
540
541bool QDtls::setPeer(
const QHostAddress &address, quint16 port,
542 const QString &verificationName)
546 auto *backend = d->backend.get();
550 if (backend->state() != HandshakeNotStarted) {
551 backend->setDtlsError(QDtlsError::InvalidOperation,
552 tr(
"Cannot set peer after handshake started"));
556 if (address.isNull()) {
557 backend->setDtlsError(QDtlsError::InvalidInputParameters,
558 tr(
"Invalid address"));
562 if (address.isBroadcast() || address.isMulticast()) {
563 backend->setDtlsError(QDtlsError::InvalidInputParameters,
564 msgUnsupportedMulticastAddress());
568 backend->clearDtlsError();
569 backend->setPeer(address, port, verificationName);
575
576
577
578
579
580
581
582bool QDtls::setPeerVerificationName(
const QString &name)
586 auto *backend = d->backend.get();
590 if (backend->state() != HandshakeNotStarted) {
591 backend->setDtlsError(QDtlsError::InvalidOperation,
592 tr(
"Cannot set verification name after handshake started"));
596 backend->clearDtlsError();
597 backend->setPeerVerificationName(name);
603
604
605
606
607QHostAddress QDtls::peerAddress()
const
611 if (
const auto *backend = d->backend.get())
612 return backend->peerAddress();
618
619
620
621
622quint16 QDtls::peerPort()
const
626 if (
const auto *backend = d->backend.get())
627 return backend->peerPort();
633
634
635
636
637
638QString QDtls::peerVerificationName()
const
642 if (
const auto *backend = d->backend.get())
643 return backend->peerVerificationName();
649
650
651
652
653
654QSslSocket::SslMode QDtls::sslMode()
const
658 if (
const auto *backend = d->backend.get())
659 return backend->cryptographMode();
661 return QSslSocket::UnencryptedMode;
665
666
667
668
669
670void QDtls::setMtuHint(quint16 mtuHint)
674 if (
auto *backend = d->backend.get())
675 backend->setDtlsMtuHint(mtuHint);
679
680
681
682
683quint16 QDtls::mtuHint()
const
687 if (
const auto *backend = d->backend.get())
688 return backend->dtlsMtuHint();
694
695
696
697
698
699
700
701
702
703bool QDtls::setCookieGeneratorParameters(
const GeneratorParameters ¶ms)
707 if (
auto *backend = d->backend.get())
708 backend->setCookieGeneratorParameters(params);
714
715
716
717
718
719
720
721
722
723
724QDtls::GeneratorParameters QDtls::cookieGeneratorParameters()
const
728 if (
const auto *backend = d->backend.get())
729 return backend->cookieGeneratorParameters();
735
736
737
738
739
740
741
742bool QDtls::setDtlsConfiguration(
const QSslConfiguration &configuration)
746 auto *backend = d->backend.get();
750 if (backend->state() != HandshakeNotStarted) {
751 backend->setDtlsError(QDtlsError::InvalidOperation,
752 tr(
"Cannot set configuration after handshake started"));
756 backend->setConfiguration(configuration);
761
762
763
764
765
766QSslConfiguration QDtls::dtlsConfiguration()
const
769 if (
const auto *backend = d->backend.get())
770 return backend->configuration();
776
777
778
779
780QDtls::HandshakeState QDtls::handshakeState()
const
784 if (
const auto *backend = d->backend.get())
785 return backend->state();
787 return QDtls::HandshakeNotStarted;
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809bool QDtls::doHandshake(QUdpSocket *socket,
const QByteArray &dgram)
813 auto *backend = d->backend.get();
817 if (backend->state() == HandshakeNotStarted)
818 return startHandshake(socket, dgram);
819 else if (backend->state() == HandshakeInProgress)
820 return continueHandshake(socket, dgram);
822 backend->setDtlsError(QDtlsError::InvalidOperation,
823 tr(
"Cannot start/continue handshake, invalid handshake state"));
828
829
830bool QDtls::startHandshake(QUdpSocket *socket,
const QByteArray &datagram)
834 auto *backend = d->backend.get();
839 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
843 if (backend->peerAddress().isNull()) {
844 backend->setDtlsError(QDtlsError::InvalidOperation,
845 tr(
"To start a handshake you must set peer's address and port first"));
849 if (sslMode() == QSslSocket::SslServerMode && !datagram.size()) {
850 backend->setDtlsError(QDtlsError::InvalidInputParameters,
851 tr(
"To start a handshake, DTLS server requires non-empty datagram (client hello)"));
855 if (backend->state() != HandshakeNotStarted) {
856 backend->setDtlsError(QDtlsError::InvalidOperation,
857 tr(
"Cannot start handshake, already done/in progress"));
861 return backend->startHandshake(socket, datagram);
865
866
867
868
869
870
871
872bool QDtls::handleTimeout(QUdpSocket *socket)
876 auto *backend = d->backend.get();
881 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
885 return backend->handleTimeout(socket);
889
890
891bool QDtls::continueHandshake(QUdpSocket *socket,
const QByteArray &datagram)
895 auto *backend = d->backend.get();
899 if (!socket || !datagram.size()) {
900 backend->setDtlsError(QDtlsError::InvalidInputParameters,
901 tr(
"A valid QUdpSocket and non-empty datagram are needed to continue the handshake"));
905 if (backend->state() != HandshakeInProgress) {
906 backend->setDtlsError(QDtlsError::InvalidOperation,
907 tr(
"Cannot continue handshake, not in InProgress state"));
911 return backend->continueHandshake(socket, datagram);
915
916
917
918
919
920
921
922bool QDtls::resumeHandshake(QUdpSocket *socket)
926 auto *backend = d->backend.get();
931 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
935 if (backend->state() != PeerVerificationFailed) {
936 backend->setDtlsError(QDtlsError::InvalidOperation,
937 tr(
"Cannot resume, not in VerificationError state"));
941 return backend->resumeHandshake(socket);
945
946
947
948
949
950bool QDtls::abortHandshake(QUdpSocket *socket)
954 auto *backend = d->backend.get();
959 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
963 if (backend->state() != PeerVerificationFailed && backend->state() != HandshakeInProgress) {
964 backend->setDtlsError(QDtlsError::InvalidOperation,
965 tr(
"No handshake in progress, nothing to abort"));
969 backend->abortHandshake(socket);
974
975
976
977
978
979
980bool QDtls::shutdown(QUdpSocket *socket)
984 auto *backend = d->backend.get();
989 backend->setDtlsError(QDtlsError::InvalidInputParameters,
990 tr(
"Invalid (nullptr) socket"));
994 if (!backend->isConnectionEncrypted()) {
995 backend->setDtlsError(QDtlsError::InvalidOperation,
996 tr(
"Cannot send shutdown alert, not encrypted"));
1000 backend->sendShutdownAlert(socket);
1005
1006
1007
1008
1009bool QDtls::isConnectionEncrypted()
const
1014 if (
const auto *backend = d->backend.get())
1015 return backend->isConnectionEncrypted();
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032QSslCipher QDtls::sessionCipher()
const
1036 if (
const auto *backend = d->backend.get())
1037 return backend->dtlsSessionCipher();
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052QSsl::SslProtocol QDtls::sessionProtocol()
const
1056 if (
const auto *backend = d->backend.get())
1057 return backend->dtlsSessionProtocol();
1059 return QSsl::UnknownProtocol;
1063
1064
1065
1066
1067
1068
1069
1070qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket,
const QByteArray &dgram)
1074 auto *backend = d->backend.get();
1079 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
1083 if (!isConnectionEncrypted()) {
1084 backend->setDtlsError(QDtlsError::InvalidOperation,
1085 tr(
"Cannot write a datagram, not in encrypted state"));
1089 return backend->writeDatagramEncrypted(socket, dgram);
1093
1094
1095
1096
1097
1098QByteArray QDtls::decryptDatagram(QUdpSocket *socket,
const QByteArray &dgram)
1102 auto *backend = d->backend.get();
1107 backend->setDtlsError(QDtlsError::InvalidInputParameters, tr(
"Invalid (nullptr) socket"));
1111 if (!isConnectionEncrypted()) {
1112 backend->setDtlsError(QDtlsError::InvalidOperation,
1113 tr(
"Cannot read a datagram, not in encrypted state"));
1120 return backend->decryptDatagram(socket, dgram);
1124
1125
1126
1127
1128QDtlsError QDtls::dtlsError()
const
1132 if (
const auto *backend = d->backend.get())
1133 return backend->error();
1135 return QDtlsError::NoError;
1139
1140
1141
1142
1143
1144QString QDtls::dtlsErrorString()
const
1148 if (
const auto *backend = d->backend.get())
1149 return backend->errorString();
1155
1156
1157
1158
1159
1160QList<QSslError> QDtls::peerVerificationErrors()
const
1164 if (
const auto *backend = d->backend.get())
1165 return backend->peerVerificationErrors();
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189void QDtls::ignoreVerificationErrors(
const QList<QSslError> &errorsToIgnore)
1193 if (
auto *backend = d->backend.get())
1194 backend->ignoreVerificationErrors(errorsToIgnore);
1199#include "moc_qdtls.cpp"
QDtlsClientVerifierPrivate()
~QDtlsClientVerifierPrivate()
static QT_BEGIN_NAMESPACE QString msgUnsupportedMulticastAddress()