aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2019-05-22 16:10:39 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2019-05-22 16:10:39 +0200
commit430a041c2ce117282a5ef660b65d0a81f61c00b7 (patch)
treeeb030b29d0b1017e671f1633fbcd5a9c4b8d5a9f
parentd2744ade327fe6b63bb80d6acd9c1cd7ae6e317f (diff)
Add a method for setting the minimum token size
For security reasons it is recommended to use tokens with a length of at least 4 bytes. Added a method for setting the minimum token size and changed it to be 4 by default. Change-Id: Ib589b338df8e59ccaf24dceab6691f92d92f861c Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/coap/qcoapclient.cpp12
-rw-r--r--src/coap/qcoapclient.h1
-rw-r--r--src/coap/qcoapprotocol.cpp24
-rw-r--r--src/coap/qcoapprotocol_p.h2
-rw-r--r--tests/auto/qcoapclient/tst_qcoapclient.cpp45
5 files changed, 81 insertions, 3 deletions
diff --git a/src/coap/qcoapclient.cpp b/src/coap/qcoapclient.cpp
index 4ff4ced..76fee53 100644
--- a/src/coap/qcoapclient.cpp
+++ b/src/coap/qcoapclient.cpp
@@ -690,4 +690,16 @@ void QCoapClient::setMaximumRetransmitCount(uint maximumRetransmitCount)
Q_ARG(uint, maximumRetransmitCount));
}
+/*!
+ Sets the minimum token size to \a tokenSize in bytes. For security reasons it is
+ recommended to use tokens with a length of at least 4 bytes. The default value for
+ this parameter is 4 bytes.
+*/
+void QCoapClient::setMinumumTokenSize(int tokenSize)
+{
+ Q_D(QCoapClient);
+ QMetaObject::invokeMethod(d->protocol, "setMinumumTokenSize", Qt::QueuedConnection,
+ Q_ARG(int, tokenSize));
+}
+
QT_END_NAMESPACE
diff --git a/src/coap/qcoapclient.h b/src/coap/qcoapclient.h
index 31bf9f2..c273aa1 100644
--- a/src/coap/qcoapclient.h
+++ b/src/coap/qcoapclient.h
@@ -88,6 +88,7 @@ public:
void setAckTimeout(uint ackTimeout);
void setAckRandomFactor(double ackRandomFactor);
void setMaximumRetransmitCount(uint maximumRetransmitCount);
+ void setMinumumTokenSize(int tokenSize);
Q_SIGNALS:
void finished(QCoapReply *reply);
diff --git a/src/coap/qcoapprotocol.cpp b/src/coap/qcoapprotocol.cpp
index 46f420c..33ca9d7 100644
--- a/src/coap/qcoapprotocol.cpp
+++ b/src/coap/qcoapprotocol.cpp
@@ -690,9 +690,7 @@ QCoapToken QCoapProtocolPrivate::generateUniqueToken() const
// TODO: Store used token for the period specified by CoAP spec
QCoapToken token;
while (isTokenRegistered(token)) {
- // TODO: Allow setting minimum token size as a security setting
- quint8 length = static_cast<quint8>(QtCoap::randomGenerator().bounded(1, 8));
-
+ quint8 length = static_cast<quint8>(QtCoap::randomGenerator().bounded(minimumTokenSize, 9));
token.resize(length);
quint8 *tokenData = reinterpret_cast<quint8 *>(token.data());
for (int i = 0; i < token.size(); ++i)
@@ -1151,4 +1149,24 @@ void QCoapProtocol::setMaximumServerResponseDelay(uint responseDelay)
d->maximumServerResponseDelay = responseDelay;
}
+/*!
+ \internal
+
+ Sets the minimum token size to \a tokenSize in bytes. For security reasons it is
+ recommended to use tokens with a length of at least 4 bytes. The default value for
+ this parameter is 4 bytes.
+*/
+void QCoapProtocol::setMinumumTokenSize(int tokenSize)
+{
+ Q_D(QCoapProtocol);
+
+ if (tokenSize > 0 && tokenSize <= 8) {
+ d->minimumTokenSize = tokenSize;
+ } else {
+ qCWarning(lcCoapProtocol,
+ "Failed to set the minimum token size,"
+ "it should not be more than 8 bytes and cannot be 0.");
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/coap/qcoapprotocol_p.h b/src/coap/qcoapprotocol_p.h
index b24363e..4a7c61e 100644
--- a/src/coap/qcoapprotocol_p.h
+++ b/src/coap/qcoapprotocol_p.h
@@ -90,6 +90,7 @@ public:
Q_INVOKABLE void setMaximumRetransmitCount(uint maximumRetransmitCount);
Q_INVOKABLE void setBlockSize(quint16 blockSize);
Q_INVOKABLE void setMaximumServerResponseDelay(uint responseDelay);
+ Q_INVOKABLE void setMinumumTokenSize(int tokenSize);
private:
Q_INVOKABLE void sendRequest(QPointer<QCoapReply> reply, QCoapConnection *connection);
@@ -161,6 +162,7 @@ public:
uint maximumRetransmitCount = 4;
uint ackTimeout = 2000;
uint maximumServerResponseDelay = 250 * 1000;
+ int minimumTokenSize = 4;
double ackRandomFactor = 1.5;
Q_DECLARE_PUBLIC(QCoapProtocol)
diff --git a/tests/auto/qcoapclient/tst_qcoapclient.cpp b/tests/auto/qcoapclient/tst_qcoapclient.cpp
index 0af3bee..aa8f70f 100644
--- a/tests/auto/qcoapclient/tst_qcoapclient.cpp
+++ b/tests/auto/qcoapclient/tst_qcoapclient.cpp
@@ -77,6 +77,8 @@ private Q_SLOTS:
void confirmableMulticast();
void multicast();
void multicast_blockwise();
+ void setMinimumTokenSize_data();
+ void setMinimumTokenSize();
};
#ifdef QT_BUILD_INTERNAL
@@ -871,6 +873,49 @@ void tst_QCoapClient::multicast_blockwise()
#endif
}
+void tst_QCoapClient::setMinimumTokenSize_data()
+{
+ QTest::addColumn<int>("minTokenSize");
+ QTest::addColumn<int>("expectedMinSize");
+
+ QTest::newRow("in_range") << 6 << 6;
+ QTest::newRow("out_of_range_small") << 0 << 4;
+ QTest::newRow("out_of_range_big") << 9 << 4;
+}
+
+void noMessageOutput(QtMsgType, const QMessageLogContext &, const QString &) {}
+
+void tst_QCoapClient::setMinimumTokenSize()
+{
+#ifdef QT_BUILD_INTERNAL
+ // Don't show warning messages for the out of range values
+ qInstallMessageHandler(noMessageOutput);
+
+ QFETCH(int, minTokenSize);
+ QFETCH(int, expectedMinSize);
+
+ const int maxSize = 8;
+
+ for (int i = 0; i < 20; ++i) {
+ QCoapClientForSocketErrorTests client;
+ client.setMinumumTokenSize(minTokenSize);
+
+ // With QCoapClientForSocketErrorTests the request will fail, but it doesn't matter,
+ // we are interested only in the generated token.
+ QSignalSpy spyClientError(&client, &QCoapClient::error);
+
+ QScopedPointer<QCoapReply> reply;
+ reply.reset(client.get(QCoapRequest("127.0.0.1")));
+
+ QTRY_COMPARE_WITH_TIMEOUT(spyClientError.count(), 1, 10);
+ QVERIFY(reply->request().tokenLength() >= expectedMinSize);
+ QVERIFY(reply->request().tokenLength() <= maxSize);
+ }
+#else
+ QSKIP("Not an internal build, skipping this test");
+#endif
+}
+
QTEST_MAIN(tst_QCoapClient)
#include "tst_qcoapclient.moc"