diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2019-05-07 15:06:59 +0200 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2019-07-17 12:27:28 +0200 |
commit | 13d450eff784aedc8d005c0da76503647a30a934 (patch) | |
tree | f8ab91f65adf943dc744154f717fd21272317479 | |
parent | 3e83021fbc9f0cec25ebdbf3683ac91562a2192b (diff) |
Add security tests
Change-Id: I2e227977f1b8d407b4c9b069d2a18043cef844c2
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r-- | tests/auto/coapnetworksettings.h | 64 | ||||
-rw-r--r-- | tests/auto/qcoapclient/qcoapclient.pro | 2 | ||||
-rw-r--r-- | tests/auto/qcoapclient/testdata/ca_cert.pem | 12 | ||||
-rw-r--r-- | tests/auto/qcoapclient/testdata/local_cert.pem | 13 | ||||
-rw-r--r-- | tests/auto/qcoapclient/testdata/privkey.pem | 40 | ||||
-rw-r--r-- | tests/auto/qcoapclient/tst_qcoapclient.cpp | 340 |
6 files changed, 374 insertions, 97 deletions
diff --git a/tests/auto/coapnetworksettings.h b/tests/auto/coapnetworksettings.h index 3dc5534..acda397 100644 --- a/tests/auto/coapnetworksettings.h +++ b/tests/auto/coapnetworksettings.h @@ -32,6 +32,7 @@ #include <QtCore/qstring.h> #include <QtNetwork/qhostinfo.h> #include <QtCoap/qcoapclient.h> +#include <QtCoap/qcoapsecurityconfiguration.h> /*! \internal @@ -97,6 +98,12 @@ QString testServerHost() return testServerHostAddress; } +QString timeServerUrl() +{ + static QString timeServerHostAddress = getHostAddress("freecoap"); + return QStringLiteral("coaps://") + timeServerHostAddress + QStringLiteral(":5685/time"); +} + QString testServerUrl() { return QStringLiteral("coap://") + testServerHost() + QStringLiteral(":") @@ -105,13 +112,64 @@ QString testServerUrl() QString testServerResource() { - return testServerUrl() + QStringLiteral("/test"); + return testServerHost() + QStringLiteral("/test"); } -bool waitForHost(const QUrl &url, quint8 retries = 10) +QCoapSecurityConfiguration createConfiguration(QtCoap::SecurityMode securityMode) +{ + QCoapSecurityConfiguration configuration; + + if (securityMode == QtCoap::SecurityMode::PreSharedKey) { + configuration.setPreSharedKeyIdentity("Client_identity"); + configuration.setPreSharedKey("secretPSK"); + } else if (securityMode == QtCoap::SecurityMode::Certificate) { + const QString directory = QFINDTESTDATA("testdata"); + if (directory.isEmpty()) { + qWarning() << "Found no testdata/, cannot load certificates."; + return configuration; + } + + const auto localCertPath = directory + QDir::separator() +"local_cert.pem"; + const auto localCerts = QSslCertificate::fromPath(localCertPath); + if (localCerts.isEmpty()) { + qWarning() << "Failed to load local certificates, the" + << localCertPath + << "file was not found or it is not valid."; + } else { + configuration.setLocalCertificateChain(localCerts.toVector()); + } + + const auto caCertPath = directory + QDir::separator() + "ca_cert.pem"; + const auto caCerts = QSslCertificate::fromPath(caCertPath); + if (caCerts.isEmpty()) { + qWarning() << "Failed to load CA certificates, the" + << caCertPath + << "file was not found or it is not valid."; + } else { + configuration.setCaCertificates(caCerts.toVector()); + } + + const auto privateKeyPath = directory + QDir::separator() + "privkey.pem"; + QFile privateKey(privateKeyPath); + if (privateKey.open(QIODevice::ReadOnly)) { + QCoapPrivateKey key(privateKey.readAll(), QSsl::Ec); + configuration.setPrivateKey(key); + } else { + qWarning() << "Failed to read the private key" << privateKeyPath; + } + } + + return configuration; +} + +bool waitForHost(const QUrl &url, QtCoap::SecurityMode security = QtCoap::SecurityMode::NoSecurity, + quint8 retries = 10) { while (retries-- > 0) { - QCoapClient client; + QCoapClient client(security); + if (security != QtCoap::SecurityMode::NoSecurity) + client.setSecurityConfiguration(createConfiguration(security)); + QSignalSpy spyClientFinished(&client, SIGNAL(finished(QCoapReply *))); client.get(url); diff --git a/tests/auto/qcoapclient/qcoapclient.pro b/tests/auto/qcoapclient/qcoapclient.pro index 1483994..59cfc4f 100644 --- a/tests/auto/qcoapclient/qcoapclient.pro +++ b/tests/auto/qcoapclient/qcoapclient.pro @@ -8,4 +8,4 @@ HEADERS += ../coapnetworksettings.h SOURCES += tst_qcoapclient.cpp CONFIG += unsupported/testserver -QT_TEST_SERVER_LIST = californium +QT_TEST_SERVER_LIST = californium freecoap diff --git a/tests/auto/qcoapclient/testdata/ca_cert.pem b/tests/auto/qcoapclient/testdata/ca_cert.pem new file mode 100644 index 0000000..4f08468 --- /dev/null +++ b/tests/auto/qcoapclient/testdata/ca_cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBrTCCAVOgAwIBAgIMWBtPBCPy5ZOTqJ69MAoGCCqGSM49BAMCMDgxEzARBgNV +BAMTCmR1bW15L3Jvb3QxETAPBgNVBAsTCFNvZnR3YXJlMQ4wDAYDVQQKEwVEdW1t +eTAeFw0xNjExMDMxNDUxNDhaFw0yNjExMDExNDUxNDhaMDgxEzARBgNVBAMTCmR1 +bW15L3Jvb3QxETAPBgNVBAsTCFNvZnR3YXJlMQ4wDAYDVQQKEwVEdW1teTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABMJ6XvBwMC3sZRyBatX95w+/AieUhN1cNfWI +Uc4HA0IXp+WwDN7QXd7mm1FDV/wQmNx/y2MJ7OQMJUvSozRPpfKjQzBBMA8GA1Ud +EwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQUsib+R29JtRKp +G6duvLrDjM8PySUwCgYIKoZIzj0EAwIDSAAwRQIgQC6ZVZi6sXnYypt1CKlDSS2Q +W+CV62TyOdE9j9phNfECIQDno7uEc8sXHnwkCcfuZhFVAkEfE8KBPhEF7ZmqJz5c +BQ== +-----END CERTIFICATE----- diff --git a/tests/auto/qcoapclient/testdata/local_cert.pem b/tests/auto/qcoapclient/testdata/local_cert.pem new file mode 100644 index 0000000..0f51a36 --- /dev/null +++ b/tests/auto/qcoapclient/testdata/local_cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4jCCAYigAwIBAgIMWBtPBCa+RXwaSLCOMAoGCCqGSM49BAMCMDgxEzARBgNV +BAMTCmR1bW15L3Jvb3QxETAPBgNVBAsTCFNvZnR3YXJlMQ4wDAYDVQQKEwVEdW1t +eTAeFw0xNjExMDMxNDUxNDhaFw0yNjExMDExNDUxNDhaMDoxFTATBgNVBAMTDGR1 +bW15L2NsaWVudDERMA8GA1UECxMIU29mdHdhcmUxDjAMBgNVBAoTBUR1bW15MFkw +EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcrIeFXrfmAu/fiT49ToNubG6u/w5GAQb +xI0V7vmFCxFSn4ttoPfEUMlUKCTFYc6HbzmFgUjct1KFGBuAfZ13M6N2MHQwDAYD +VR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AA +MB0GA1UdDgQWBBSc2q9vjtlLW1IUSzDa9X2qnJYU1DAfBgNVHSMEGDAWgBQEbS8W +F1883YRUvUnCBnkSs/NhmjAKBggqhkjOPQQDAgNIADBFAiEA9fZYVTMn9My9erGO +j5tFYsGj4A7CkWHFRj50KirZN4ECIFLEmt5SbmipqFdkiRBxkjkJEMYC+iLBeMqI +Cgi5tYDF +-----END CERTIFICATE----- diff --git a/tests/auto/qcoapclient/testdata/privkey.pem b/tests/auto/qcoapclient/testdata/privkey.pem new file mode 100644 index 0000000..75dee45 --- /dev/null +++ b/tests/auto/qcoapclient/testdata/privkey.pem @@ -0,0 +1,40 @@ +Public Key Info: + Public Key Algorithm: EC/ECDSA + Key Security Level: High (256 bits) + +curve: SECP256R1 +private key: + 00:f7:ea:23:23:78:12:38:e3:8f:e0:2b:05:72:2f:6a + 24:91:a0:54:c6:3d:ed:68:ce:6e:60:8d:0f:fd:9f:39 + c6: + +x: + 72:b2:1e:15:7a:df:98:0b:bf:7e:24:f8:f5:3a:0d:b9 + b1:ba:bb:fc:39:18:04:1b:c4:8d:15:ee:f9:85:0b:11 + + +y: + 52:9f:8b:6d:a0:f7:c4:50:c9:54:28:24:c5:61:ce:87 + 6f:39:85:81:48:dc:b7:52:85:18:1b:80:7d:9d:77:33 + + + +Public Key ID: 9C:DA:AF:6F:8E:D9:4B:5B:52:14:4B:30:DA:F5:7D:AA:9C:96:14:D4 +Public key's random art: ++--[SECP256R1]----+ +| o.=. | +| o = +E. | +| . . + . o| +| . . . . ..| +| S o . | +| o + + | +| . . o B | +| *.= | +| +=B. | ++-----------------+ + +-----BEGIN EC PRIVATE KEY----- +MHgCAQEEIQD36iMjeBI444/gKwVyL2okkaBUxj3taM5uYI0P/Z85xqAKBggqhkjO +PQMBB6FEA0IABHKyHhV635gLv34k+PU6Dbmxurv8ORgEG8SNFe75hQsRUp+LbaD3 +xFDJVCgkxWHOh285hYFI3LdShRgbgH2ddzM= +-----END EC PRIVATE KEY----- diff --git a/tests/auto/qcoapclient/tst_qcoapclient.cpp b/tests/auto/qcoapclient/tst_qcoapclient.cpp index f938a04..696a6b6 100644 --- a/tests/auto/qcoapclient/tst_qcoapclient.cpp +++ b/tests/auto/qcoapclient/tst_qcoapclient.cpp @@ -37,6 +37,7 @@ #include <QtCoap/qcoapresourcediscoveryreply.h> #include <QtCore/qbuffer.h> #include <QtNetwork/qnetworkdatagram.h> +#include <QtNetwork/qsslcipher.h> #include <private/qcoapclient_p.h> #include <private/qcoapqudpconnection_p.h> #include <private/qcoapprotocol_p.h> @@ -66,6 +67,7 @@ private Q_SLOTS: void setBlockSize(); void requestWithQIODevice_data(); void requestWithQIODevice(); + void multipleRequests_data(); void multipleRequests(); void blockwiseReply_data(); void blockwiseReply(); @@ -82,8 +84,40 @@ private Q_SLOTS: void setMinimumTokenSize(); }; -#ifdef QT_BUILD_INTERNAL +class QCoapClientForSecurityTests : public QCoapClient +{ +public: + QCoapClientForSecurityTests(QtCoap::SecurityMode security) + : QCoapClient(security) + , securityMode(security) + { + if (security != QtCoap::SecurityMode::NoSecurity) + setSecurityConfiguration(createConfiguration(security)); + } + + bool securityMissing() const + { +#if QT_CONFIG(dtls) + if (securityMode == QtCoap::SecurityMode::PreSharedKey) { + const auto ciphers = QSslConfiguration::defaultDtlsConfiguration().ciphers(); + const auto it = std::find_if(ciphers.cbegin(), ciphers.cend(), + [](const QSslCipher &cipher) { + return cipher.name() == "PSK-AES128-CCM8" + || cipher.name() == "PSK-AES128-CBC-SHA256"; + }); + return it == ciphers.cend(); + } + return false; +#else + return true; +#endif + } + +private: + QtCoap::SecurityMode securityMode; +}; +#ifdef QT_BUILD_INTERNAL class QCoapQUdpConnectionSocketTestsPrivate : public QCoapQUdpConnectionPrivate { bool bind() override @@ -199,6 +233,10 @@ void tst_QCoapClient::initTestCase() { #if defined(COAP_TEST_SERVER_IP) || defined(QT_TEST_SERVER) QVERIFY2(waitForHost(testServerHost()), "Failed to connect to Californium plugtest server."); +#if QT_CONFIG(dtls) + QVERIFY2(waitForHost(timeServerUrl(), QtCoap::SecurityMode::Certificate), + "Failed to connect to FreeCoAP sample time server."); +#endif #endif } @@ -243,24 +281,59 @@ void tst_QCoapClient::methods_data() { QTest::addColumn<QUrl>("url"); QTest::addColumn<QtCoap::Method>("method"); - - QTest::newRow("get") << QUrl(testServerResource()) << QtCoap::Method::Get; - QTest::newRow("get_no_port") << QUrl("coap://" + testServerHost() + "/test") - << QtCoap::Method::Get; - QTest::newRow("get_no_scheme_no_port") << QUrl(testServerHost() + "/test") - << QtCoap::Method::Get; - QTest::newRow("post") << QUrl(testServerResource()) - << QtCoap::Method::Post; - QTest::newRow("post_no_scheme_no_port") << QUrl(testServerHost() + "/test") - << QtCoap::Method::Post; - QTest::newRow("put") << QUrl(testServerResource()) - << QtCoap::Method::Put; - QTest::newRow("put_no_scheme_no_port") << QUrl(testServerHost() + "/test") - << QtCoap::Method::Put; - QTest::newRow("delete") << QUrl(testServerResource()) - << QtCoap::Method::Delete; - QTest::newRow("delete_no_scheme_no_port") << QUrl(testServerHost() + "/test") - << QtCoap::Method::Delete; + QTest::addColumn<QtCoap::SecurityMode>("security"); + + QTest::newRow("get") + << QUrl(testServerResource()) + << QtCoap::Method::Get + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("get_no_port") + << QUrl("coap://" + testServerHost() + "/test") + << QtCoap::Method::Get + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("get_no_scheme_no_port") + << QUrl(testServerHost() + "/test") + << QtCoap::Method::Get + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("get_psk") + << QUrl(testServerResource()) << QtCoap::Method::Get + << QtCoap::SecurityMode::PreSharedKey; + QTest::newRow("get_cert") + << QUrl(timeServerUrl()) << QtCoap::Method::Get + << QtCoap::SecurityMode::Certificate; + QTest::newRow("post") + << QUrl(testServerResource()) + << QtCoap::Method::Post + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("post_no_scheme_no_port") + << QUrl(testServerHost() + "/test") + << QtCoap::Method::Post + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("post_psk") + << QUrl(testServerResource()) << QtCoap::Method::Post + << QtCoap::SecurityMode::PreSharedKey; + QTest::newRow("put") + << QUrl(testServerResource()) + << QtCoap::Method::Put + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("put_no_scheme_no_port") + << QUrl(testServerHost() + "/test") + << QtCoap::Method::Put + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("put_psk") + << QUrl(testServerResource()) << QtCoap::Method::Put + << QtCoap::SecurityMode::PreSharedKey; + QTest::newRow("delete") + << QUrl(testServerResource()) + << QtCoap::Method::Delete + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("delete_no_scheme_no_port") + << QUrl(testServerHost() + "/test") + << QtCoap::Method::Delete + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("delete_psk") + << QUrl(testServerResource()) << QtCoap::Method::Delete + << QtCoap::SecurityMode::PreSharedKey; } void tst_QCoapClient::methods() @@ -269,8 +342,12 @@ void tst_QCoapClient::methods() QFETCH(QUrl, url); QFETCH(QtCoap::Method, method); + QFETCH(QtCoap::SecurityMode, security); + + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); - QCoapClient client; QCoapRequest request(url); QSignalSpy spyClientFinished(&client, SIGNAL(finished(QCoapReply *))); @@ -291,7 +368,8 @@ void tst_QCoapClient::methods() QVERIFY2(!reply.isNull(), "Request failed unexpectedly"); #ifdef QT_BUILD_INTERNAL - QCOMPARE(reply->url(), QCoapRequestPrivate::adjustedUrl(url, false)); + QCOMPARE(reply->url(), + QCoapRequestPrivate::adjustedUrl(url, security != QtCoap::SecurityMode::NoSecurity)); #endif QSignalSpy spyReplyFinished(reply.data(), SIGNAL(finished(QCoapReply *))); QTRY_COMPARE(spyReplyFinished.count(), 1); @@ -430,51 +508,56 @@ void tst_QCoapClient::requestWithQIODevice() } } +void tst_QCoapClient::multipleRequests_data() +{ + QTest::addColumn<QtCoap::SecurityMode>("security"); + + QTest::newRow("multiple_requests") << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("multiple_requests_secure") << QtCoap::SecurityMode::PreSharedKey; +} + void tst_QCoapClient::multipleRequests() { CHECK_FOR_COAP_SERVER; - QCoapClient client; + QFETCH(QtCoap::SecurityMode, security); + + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); + QUrl url = QUrl(testServerResource()); QSignalSpy spyClientFinished(&client, SIGNAL(finished(QCoapReply *))); - QScopedPointer<QCoapReply> replyGet1(client.get(url)); - QScopedPointer<QCoapReply> replyGet2(client.get(url)); - QScopedPointer<QCoapReply> replyGet3(client.get(url)); - QScopedPointer<QCoapReply> replyGet4(client.get(url)); - - QVERIFY2(!replyGet1.isNull(), "Request failed unexpectedly"); - QVERIFY2(!replyGet2.isNull(), "Request failed unexpectedly"); - QVERIFY2(!replyGet3.isNull(), "Request failed unexpectedly"); - QVERIFY2(!replyGet4.isNull(), "Request failed unexpectedly"); - - QSignalSpy spyReplyGet1Finished(replyGet1.data(), SIGNAL(finished(QCoapReply *))); - QSignalSpy spyReplyGet2Finished(replyGet2.data(), SIGNAL(finished(QCoapReply *))); - QSignalSpy spyReplyGet3Finished(replyGet3.data(), SIGNAL(finished(QCoapReply *))); - QSignalSpy spyReplyGet4Finished(replyGet4.data(), SIGNAL(finished(QCoapReply *))); - - QTRY_COMPARE(spyReplyGet1Finished.count(), 1); - QTRY_COMPARE(spyReplyGet2Finished.count(), 1); - QTRY_COMPARE(spyReplyGet3Finished.count(), 1); - QTRY_COMPARE(spyReplyGet4Finished.count(), 1); + const uint8_t requestCount = 4; + QVector<QSharedPointer<QCoapReply>> replies; + QVector<QSharedPointer<QSignalSpy>> signalSpies; + for (uint8_t i = 0; i < requestCount; ++i) { + QCoapRequest request; + const auto token = "token" + QByteArray::number(i); + request.setToken(token); + request.setUrl(url); + + QSharedPointer<QCoapReply> reply(client.get(request)); + const auto errorMsg = QStringLiteral("Request number %1 failed unexpectedly").arg(i); + QVERIFY2(!reply.isNull(), qPrintable(errorMsg)); + replies.push_back(reply); + + QSharedPointer<QSignalSpy> signalSpy( + new QSignalSpy(reply.data(), SIGNAL(finished(QCoapReply *)))); + signalSpies.push_back(signalSpy); + } + + for (const auto &signalSpy : signalSpies) + QTRY_COMPARE(signalSpy->count(), 1); QTRY_COMPARE(spyClientFinished.count(), 4); - QByteArray replyData1 = replyGet1->readAll(); - QByteArray replyData2 = replyGet2->readAll(); - QByteArray replyData3 = replyGet3->readAll(); - QByteArray replyData4 = replyGet4->readAll(); - - QCOMPARE(replyGet1->responseCode(), QtCoap::ResponseCode::Content); - QCOMPARE(replyGet2->responseCode(), QtCoap::ResponseCode::Content); - QCOMPARE(replyGet3->responseCode(), QtCoap::ResponseCode::Content); - QCOMPARE(replyGet4->responseCode(), QtCoap::ResponseCode::Content); - - QVERIFY(replyData1 != replyData2); - QVERIFY(replyData1 != replyData3); - QVERIFY(replyData1 != replyData4); - QVERIFY(replyData2 != replyData3); - QVERIFY(replyData2 != replyData4); - QVERIFY(replyData3 != replyData4); + for (uint8_t i = 0; i < requestCount; ++i) { + QCOMPARE(replies[i]->responseCode(), QtCoap::ResponseCode::Content); + QByteArray replyData = replies[i]->readAll(); + const auto token = "token" + QByteArray::number(i); + QVERIFY(replyData.contains(token.toHex())); + } } void tst_QCoapClient::socketError() @@ -591,6 +674,7 @@ void tst_QCoapClient::blockwiseReply_data() QTest::addColumn<QUrl>("url"); QTest::addColumn<QCoapMessage::Type>("type"); QTest::addColumn<QByteArray>("replyData"); + QTest::addColumn<QtCoap::SecurityMode>("security"); QByteArray data; data.append("/-------------------------------------------------------------\\\n"); @@ -617,27 +701,43 @@ void tst_QCoapClient::blockwiseReply_data() QTest::newRow("get_large") << QUrl(testServerUrl() + "/large") << QCoapMessage::Type::NonConfirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("get_large_secure") + << QUrl(testServerHost() + "/large") + << QCoapMessage::Type::NonConfirmable + << data + << QtCoap::SecurityMode::PreSharedKey; QTest::newRow("get_large_separate") - << QUrl(testServerUrl() + "/large-separate") + << QUrl(testServerHost() + "/large-separate") << QCoapMessage::Type::NonConfirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("get_large_confirmable") << QUrl(testServerUrl() + "/large") << QCoapMessage::Type::Confirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("get_large_confirmable_secure") + << QUrl(testServerHost() + "/large") + << QCoapMessage::Type::Confirmable + << data + << QtCoap::SecurityMode::PreSharedKey; QTest::newRow("get_large_separate_confirmable") << QUrl(testServerUrl() + "/large-separate") << QCoapMessage::Type::Confirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("get_large_16bits") << QUrl(testServerUrl() + "/large") << QCoapMessage::Type::NonConfirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("get_large_16bits_confirmable") << QUrl(testServerUrl() + "/large") << QCoapMessage::Type::Confirmable - << data; + << data + << QtCoap::SecurityMode::NoSecurity; } void tst_QCoapClient::blockwiseReply() @@ -647,8 +747,12 @@ void tst_QCoapClient::blockwiseReply() QFETCH(QUrl, url); QFETCH(QCoapMessage::Type, type); QFETCH(QByteArray, replyData); + QFETCH(QtCoap::SecurityMode, security); + + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); - QCoapClient client; QCoapRequest request(url); if (qstrncmp(QTest::currentDataTag(), "get_large_16bits", 16) == 0) @@ -674,22 +778,34 @@ void tst_QCoapClient::blockwiseRequest_data() QTest::addColumn<QByteArray>("requestData"); QTest::addColumn<QtCoap::ResponseCode>("responseCode"); QTest::addColumn<QByteArray>("replyData"); + QTest::addColumn<QtCoap::SecurityMode>("security"); QByteArray data; const char alphabet[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; for (int i = 3; i-- > 0; ) data.append(alphabet); - QTest::newRow("large_post_empty_reply") << QUrl(testServerUrl() + "/query") - << QCoapMessage::Type::NonConfirmable - << data - << QtCoap::ResponseCode::MethodNotAllowed - << QByteArray(); - QTest::newRow("large_post_large_reply") << QUrl(testServerUrl() + "/large-post") - << QCoapMessage::Type::NonConfirmable - << data - << QtCoap::ResponseCode::Changed - << data.toUpper(); + QTest::newRow("large_post_empty_reply") + << QUrl(testServerUrl() + "/query") + << QCoapMessage::Type::NonConfirmable + << data + << QtCoap::ResponseCode::MethodNotAllowed + << QByteArray() + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("large_post_large_reply") + << QUrl(testServerUrl() + "/large-post") + << QCoapMessage::Type::NonConfirmable + << data + << QtCoap::ResponseCode::Changed + << data.toUpper() + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("large_post_large_reply_secure") + << QUrl(testServerHost() + "/large-post") + << QCoapMessage::Type::NonConfirmable + << data + << QtCoap::ResponseCode::Changed + << data.toUpper() + << QtCoap::SecurityMode::PreSharedKey; } void tst_QCoapClient::blockwiseRequest() @@ -701,8 +817,12 @@ void tst_QCoapClient::blockwiseRequest() QFETCH(QByteArray, requestData); QFETCH(QtCoap::ResponseCode, responseCode); QFETCH(QByteArray, replyData); + QFETCH(QtCoap::SecurityMode, security); + + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); - QCoapClient client; client.setBlockSize(16); QCoapRequest request(url); @@ -724,12 +844,17 @@ void tst_QCoapClient::discover_data() { QTest::addColumn<QUrl>("url"); QTest::addColumn<int>("resourceNumber"); + QTest::addColumn<QtCoap::SecurityMode>("security"); // Californium test server exposes 29 resources - QTest::newRow("discover") << QUrl(testServerUrl()) - << 29; - QTest::newRow("discover_no_scheme_no_port") << QUrl(testServerHost()) - << 29; + QTest::newRow("discover") + << QUrl(testServerHost()) + << 29 + << QtCoap::SecurityMode::NoSecurity; + QTest::newRow("discover_secure") + << QUrl(testServerHost()) + << 29 + << QtCoap::SecurityMode::PreSharedKey; } void tst_QCoapClient::discover() @@ -738,8 +863,11 @@ void tst_QCoapClient::discover() QFETCH(QUrl, url); QFETCH(int, resourceNumber); + QFETCH(QtCoap::SecurityMode, security); - QCoapClient client; + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); QScopedPointer<QCoapResourceDiscoveryReply> resourcesReply(client.discover(url)); // /.well-known/core QVERIFY(!resourcesReply.isNull()); @@ -749,7 +877,8 @@ void tst_QCoapClient::discover() const auto discoverUrl = QUrl(url.toString() + "/.well-known/core"); #ifdef QT_BUILD_INTERNAL - QCOMPARE(resourcesReply->url(), QCoapRequestPrivate::adjustedUrl(discoverUrl, false)); + QCOMPARE(resourcesReply->url(), + QCoapRequestPrivate::adjustedUrl(discoverUrl, security != QtCoap::SecurityMode::NoSecurity)); #endif QCOMPARE(resourcesReply->resources().length(), resourceNumber); QCOMPARE(resourcesReply->request().method(), QtCoap::Method::Get); @@ -762,42 +891,62 @@ void tst_QCoapClient::observe_data() QWARN("Observe tests may take some time, don't forget to raise Tests timeout in settings."); QTest::addColumn<QUrl>("url"); QTest::addColumn<QCoapMessage::Type>("type"); + QTest::addColumn<QtCoap::SecurityMode>("security"); QTest::newRow("observe") << QUrl(testServerUrl() + "/obs") - << QCoapMessage::Type::NonConfirmable; + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::NoSecurity; + + QTest::newRow("observe_secure") + << QUrl(testServerHost() + "/obs") + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::PreSharedKey; QTest::newRow("observe_no_scheme_no_port") << QUrl(testServerHost() + "/obs") - << QCoapMessage::Type::NonConfirmable; + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_confirmable") << QUrl(testServerUrl() + "/obs") - << QCoapMessage::Type::Confirmable; + << QCoapMessage::Type::Confirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_receive") << QUrl(testServerUrl() + "/obs-non") - << QCoapMessage::Type::NonConfirmable; + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_receive_confirmable") << QUrl(testServerUrl() + "/obs-non") - << QCoapMessage::Type::Confirmable; + << QCoapMessage::Type::Confirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_large") << QUrl(testServerUrl() + "/obs-large") - << QCoapMessage::Type::NonConfirmable; + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::NoSecurity; + + QTest::newRow("observe_large_secure") + << QUrl(testServerHost() + "/obs-large") + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::PreSharedKey; QTest::newRow("observe_large_confirmable") << QUrl(testServerUrl() + "/obs-large") - << QCoapMessage::Type::Confirmable; + << QCoapMessage::Type::Confirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_pumping") << QUrl(testServerUrl() + "/obs-pumping") - << QCoapMessage::Type::NonConfirmable; + << QCoapMessage::Type::NonConfirmable + << QtCoap::SecurityMode::NoSecurity; QTest::newRow("observe_pumping_confirmable") << QUrl(testServerUrl() + "/obs-pumping") - << QCoapMessage::Type::Confirmable; + << QCoapMessage::Type::Confirmable + << QtCoap::SecurityMode::NoSecurity; } void tst_QCoapClient::observe() @@ -806,8 +955,12 @@ void tst_QCoapClient::observe() QFETCH(QUrl, url); QFETCH(QCoapMessage::Type, type); + QFETCH(QtCoap::SecurityMode, security); + + QCoapClientForSecurityTests client(security); + if (client.securityMissing()) + QSKIP("Skipping this test, security is not configured properly"); - QCoapClient client; QCoapRequest request(url); request.setType(type); @@ -820,7 +973,8 @@ void tst_QCoapClient::observe() QTRY_COMPARE_WITH_TIMEOUT(spyReplyNotified.count(), 3, 30000); client.cancelObserve(reply.data()); #ifdef QT_BUILD_INTERNAL - QCOMPARE(reply->url(), QCoapRequestPrivate::adjustedUrl(url, false)); + QCOMPARE(reply->url(), + QCoapRequestPrivate::adjustedUrl(url, security != QtCoap::SecurityMode::NoSecurity)); #endif QCOMPARE(reply->request().method(), QtCoap::Method::Get); |