summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorKai Uwe Broulik <[email protected]>2025-05-20 08:29:58 +0200
committerKai Uwe Broulik <[email protected]>2025-05-27 09:16:17 +0200
commit671afae06e9f9d228e9563c7c60a31456d2b2741 (patch)
tree700fc0846fb05b93bc126ddf20962cd7211140c8 /tests
parent5c6200c971b5478c08023f4233f248f70e09e3d7 (diff)
Add API for providing additional CA certificatesHEADdev
This allows to provide additional certificates that are considered when verifying a certificate. This is done by the cert verifier downstream of the platform-specific cert store. Fixes: QTBUG-50586 Change-Id: Ie90547f1013f22f994aaff536fadf906a44a88ef Reviewed-by: Moss Heim <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp1
-rw-r--r--tests/auto/widgets/qwebengineprofilebuilder/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/qwebengineprofilebuilder/resources/ca.pem24
-rw-r--r--tests/auto/widgets/qwebengineprofilebuilder/resources/server.key28
-rw-r--r--tests/auto/widgets/qwebengineprofilebuilder/resources/server.pem25
-rw-r--r--tests/auto/widgets/qwebengineprofilebuilder/tst_qwebengineprofilebuilder.cpp98
6 files changed, 189 insertions, 0 deletions
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 5091caf88..71844c23d 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -974,6 +974,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineProfilePrototype.persistentCookiesPolicy --> QQuickWebEngineProfile::PersistentCookiesPolicy"
<< "QQuickWebEngineProfilePrototype.httpCacheMaximumSize --> int"
<< "QQuickWebEngineProfilePrototype.persistentPermissionsPolicy --> QQuickWebEngineProfile::PersistentPermissionsPolicy"
+ << "QQuickWebEngineProfilePrototype.additionalTrustedCertificateFiles --> QStringList"
<< "QQuickWebEngineProfilePrototype.instance() --> QQuickWebEngineProfile*"
;
diff --git a/tests/auto/widgets/qwebengineprofilebuilder/CMakeLists.txt b/tests/auto/widgets/qwebengineprofilebuilder/CMakeLists.txt
index d544f3e8b..6eb28cc01 100644
--- a/tests/auto/widgets/qwebengineprofilebuilder/CMakeLists.txt
+++ b/tests/auto/widgets/qwebengineprofilebuilder/CMakeLists.txt
@@ -1,11 +1,24 @@
# Copyright (C) 2024 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
+include(../../httpserver/httpserver.cmake)
include(../../util/util.cmake)
qt_internal_add_test(tst_qwebengineprofilebuilder
SOURCES
tst_qwebengineprofilebuilder.cpp
LIBRARIES
+ Qt::TestPrivate
Qt::WebEngineWidgets
+ Test::HttpServer
+ Test::Util
+)
+
+qt_internal_add_resource(tst_qwebengineprofilebuilder "profilebuilder"
+ PREFIX
+ "/"
+ FILES
+ "resources/server.key"
+ "resources/server.pem"
+ "resources/ca.pem"
)
diff --git a/tests/auto/widgets/qwebengineprofilebuilder/resources/ca.pem b/tests/auto/widgets/qwebengineprofilebuilder/resources/ca.pem
new file mode 100644
index 000000000..c98129042
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofilebuilder/resources/ca.pem
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECzCCAvOgAwIBAgIUNmY7+SAty0eb0kNneG4LpotXUU0wDQYJKoZIhvcNAQEL
+BQAwgZQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
+cmxpbjEXMBUGA1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5n
+aW5lMRIwEAYDVQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5n
+aW5lQHF0LmlvMB4XDTI1MDUxOTEzMjYwMFoXDTM1MDUxNzEzMjYwMFowgZQxCzAJ
+BgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEXMBUG
+A1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5naW5lMRIwEAYD
+VQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5naW5lQHF0Lmlv
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhsWnavDtnG5/ZXGLWBEu
+xmeu716eWlurgG9zfZBPIgKHYw4pn+sA1HYtpgkoPf+EBBHdtI2ZI4nQpC7Yqmd1
+McYEJoMZJ0QmGeEFXzaEgrcQxFTT8SF6QO6H1h8d6KMywqBRX9pyiZv6dw3zUCWF
+YRGDWLBHTC2LhBQp3AGWm5fEi2PhyIciupaWkTwdwhuDJCJ24DU2K3XbGRL8B+ZF
+6wO0Gdhdr8FG9Gj9PsgYJCiMkJhBwa6alv5RhTKPJ0untyCpm27v/q6HyAYRzve0
+6KIr/CPNJFYj4NUTl4oMg7VZTsYYJz8tIGKEFbR0gLjKbxq1ztNGSZ1CczkavfjI
+awIDAQABo1MwUTAdBgNVHQ4EFgQUSBHNthn7rC8OkfpgK4NNI6eb9sMwHwYDVR0j
+BBgwFoAUSBHNthn7rC8OkfpgK4NNI6eb9sMwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAQEAdrmhBs49NNt8NwdhwDuDY4VrMo8TjsL9KLmk8eP7+n5j
+BW8GzM214M4Nqo5REdEbreU2MmOwla0N3akxoILFTd46Vey+SuZd86qrBejyBT30
+Hqecm7TaceFK/VjOm7N3q7WsZmxt1VQv2h/4qsRo3X0gsaG/Pa30wd95EL5Iq8UC
+noBcwSSawlyMVmb3QiGzD0h+ONlIn+AcSKjgybyoXZ3ga7fRDNuWRmSYTwgRnMWt
+D20jt9BPkOMhajCoN1tQrtKvB5s8nZTwFYJ61OnqQhOpaPSdk2mY+0Ty9xN8815D
+tejXU/6DERrGxJLrqkix/ORg3bP2kCEVMMvmJqrUCg==
+-----END CERTIFICATE-----
diff --git a/tests/auto/widgets/qwebengineprofilebuilder/resources/server.key b/tests/auto/widgets/qwebengineprofilebuilder/resources/server.key
new file mode 100644
index 000000000..593e7f174
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofilebuilder/resources/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCeqmuz7jA7uSu1
+t2qP+irhMeqHvkkFP3PRFPKoP7lThds+j8Y6mGhm3Wii01ujK7y8imoTm4am+IhF
+FT/xPs+EyKHva/TT8gjbVtR1m4jKEikQ7AEIZXMwhmR3J99zadRtJZO6qhCC7ER3
+P2BStEtxBibmZQqw0OZNsZZrIXjRX1s68j5lCA994RB1VQOIFnRgf6ZXLD1MwNtS
+9VeUwA6H/kwCCSnAO2eJgK9OgkhU+f3kY8j1tcQiwHpTBinLgbQvgy0nJJwxrV1e
+HZE5sVNuLdlS7szln/juLJ8IF3UMDvqLqDl/L7Rk+nAn4bT/P6b0IVAWyyfXQdxT
+Rml6qIgzAgMBAAECggEADUtOipJxXyevkQ0PtDBBXyyyr8dSpfUVlqtbKPFsl/d2
+Ec1eeMgOrgPCLIEUw1y69nngfnPAZLAb9tyGHDK86i1yCAtdxakYyIwDcYvjz7lA
+JfH9pNRJ7QMYWuAv5E3gkHlJYfwK4HVnHS4QZjhDaUfF2EsXX2OkJawKDurh4npU
+ICRwMG20vnAphYCw0CRbnxEBissLXpSyMDmt174jSG6houqQF8JNQUem/TG20o9X
+uhnlRvKKTeL3SN83gIx5BdHFL6uwG7qt6lUeINBjA8i0BIB37i2bu/8rOMggQFws
+G80aCdQ62vp54BcCGxBnjmljp+inU3s7quvTKOBlnQKBgQDe5UQdiWcteZlWRL+6
+b6LQ5X65UQeLTv/mi1mEfGg1UvLv2kTTu85/8Lkts1DAGj5Rb34ckGf466Y6gUkT
+c+zgucYs3n9SaboPA2fEknDJtrjdcL0xUDnPsdtgLLTmxdvaiW7uYxf36/YGFDNl
+kyG92ZC+cATSIxgiHXYg6OXQ9QKBgQC2OxCVMoib5J0jO7Uus17xQyOFV4vR07rv
+90i+diLq629TiT+ff82iKOcSPMcg1AtLquymGf1OwAmDK3+L6fpmjobR/BnXcNer
+RKJGbca8GvE+fpUTTDoGAlGD23w99LAHtoSjqxSOtIU5souLsPeBXdckJlQ+bxWe
+iqe6UEebhwKBgA3nTzBoeb8kbqQq9aqze/x71EPLAiV2cA/5cUQKXpW07uJ3QwPS
+Gzdv1J09KjRRbsG1qrAtcc7dJClSFzTXblc2P15dIqQJZEm7dKWWXOK4Ox/VAHgr
+APArr/t3znD2tpgTKpBELiKQ3W/TosEbRGeLQrQeWK6i8cZvAAddf7hhAoGAC0+3
+Q8uTNzoFlv5JzNBNgGROfCRnBWtDG0oaNdhXaoWar3DBhkEEnqAzV6p2Ic+Hs/a0
+IctTMeQxsvasQB8R7/PA4p/narwSZwsnl3+Q6nQxrVNmJYCByYWzUZ/6Ik5h7tih
+exdPe1wxONegWdduRZVxmUjXydhTWzf4GVSKXVkCgYEAqxCADKNL+TZrHqOcyENv
+vR25mUbAV8QiTX5+e9bO3STTZLZp0TWv/UxSi9Fd9tV4TijrA3ZYbJcjEuoVMNy8
+vUillTR0ZpSD2WpM1aAliR9Lh55/sTRVATgD73TUcTwpD3H887WSfPrV3oPE901i
+oSCfd2ZHwGsyCc1iYLuiC6Y=
+-----END PRIVATE KEY-----
diff --git a/tests/auto/widgets/qwebengineprofilebuilder/resources/server.pem b/tests/auto/widgets/qwebengineprofilebuilder/resources/server.pem
new file mode 100644
index 000000000..c384f8c74
--- /dev/null
+++ b/tests/auto/widgets/qwebengineprofilebuilder/resources/server.pem
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIUEcR3S839Xdw1qu4MgJi7YnhIDFEwDQYJKoZIhvcNAQEL
+BQAwgZQxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl
+cmxpbjEXMBUGA1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5n
+aW5lMRIwEAYDVQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5n
+aW5lQHF0LmlvMB4XDTI1MDUxOTEzMzYwOVoXDTM1MDUxNzEzMzYwOVowgZQxCzAJ
+BgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEXMBUG
+A1UECgwOVGhlIFF0IENvbXBhbnkxFDASBgNVBAsMC1F0V2ViRW5naW5lMRIwEAYD
+VQQDDAl3d3cucXQuaW8xIDAeBgkqhkiG9w0BCQEWEXF0d2ViZW5naW5lQHF0Lmlv
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnqprs+4wO7krtbdqj/oq
+4THqh75JBT9z0RTyqD+5U4XbPo/GOphoZt1ootNboyu8vIpqE5uGpviIRRU/8T7P
+hMih72v00/II21bUdZuIyhIpEOwBCGVzMIZkdyffc2nUbSWTuqoQguxEdz9gUrRL
+cQYm5mUKsNDmTbGWayF40V9bOvI+ZQgPfeEQdVUDiBZ0YH+mVyw9TMDbUvVXlMAO
+h/5MAgkpwDtniYCvToJIVPn95GPI9bXEIsB6UwYpy4G0L4MtJyScMa1dXh2RObFT
+bi3ZUu7M5Z/47iyfCBd1DA76i6g5fy+0ZPpwJ+G0/z+m9CFQFssn10HcU0ZpeqiI
+MwIDAQABo3AwbjAsBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABggls
+b2NhbGhvc3QwHQYDVR0OBBYEFESEhXY1rLWAZWAHyCoRCuUxsJPdMB8GA1UdIwQY
+MBaAFEgRzbYZ+6wvDpH6YCuDTSOnm/bDMA0GCSqGSIb3DQEBCwUAA4IBAQABJIpy
+SUgxsjnt0uVvsGUbXcd2tC9vYlO8B9IILZOXQ8Z47v8zq/Rly4sL9uP0eVquYEua
+/KTaJNVNzpBlrAn9GQyhZKggcaMpaUxrLsEgkBV1GDO3N93K7T/DzE8650nwrhpB
+m3SxUDvWtB5xFfGuCOv2M0oAjievnRPDvOvDq8kWJ5Oi3DyfIhP68WNS+xQdlWF2
+V+zNnhrkCyRzuTzf2BC2mofemxhx4oa3buEU/I7n/AXivvTsANHNs1GlpY7cq88p
+xeqStwaqw5+agA3tgbP0vFXorfrZnRXaim/PfbjurjGcoersQnmdJ8yEWL0y6LjS
+A0TByY327Db5AS52
+-----END CERTIFICATE-----
diff --git a/tests/auto/widgets/qwebengineprofilebuilder/tst_qwebengineprofilebuilder.cpp b/tests/auto/widgets/qwebengineprofilebuilder/tst_qwebengineprofilebuilder.cpp
index 43b754ad9..c0c087f5c 100644
--- a/tests/auto/widgets/qwebengineprofilebuilder/tst_qwebengineprofilebuilder.cpp
+++ b/tests/auto/widgets/qwebengineprofilebuilder/tst_qwebengineprofilebuilder.cpp
@@ -1,9 +1,15 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+#include <httpsserver.h>
+#include <util.h>
#include <QtTest/QtTest>
+#include <QtTest/private/qtesthelpers_p.h>
#include <QTemporaryDir>
#include <QtWebEngineCore/qwebengineprofilebuilder.h>
+#include <QtWebEngineCore/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineCore/qwebenginesettings.h>
class tst_QWebEngineProfileBuilder : public QObject
{
@@ -21,6 +27,7 @@ private Q_SLOTS:
void httpCacheSize();
void persistentPermissionsPolicy_data();
void persistentPermissionsPolicy();
+ void additionalTrustedCertificates();
void useSameDataPathForProfiles();
};
@@ -275,6 +282,97 @@ void tst_QWebEngineProfileBuilder::persistentPermissionsPolicy()
QCOMPARE(profile->persistentStoragePath(), storagePath);
}
+void tst_QWebEngineProfileBuilder::additionalTrustedCertificates()
+{
+ if (QTestPrivate::isSecureTransportBlockingTest()) {
+ QSKIP("SecureTransport will block the test server while accessing the login keychain");
+ }
+
+ QFile certFile(":/resources/server.pem");
+ QVERIFY2(certFile.open(QIODevice::ReadOnly), qPrintable(certFile.errorString()));
+ const QSslCertificate cert(&certFile, QSsl::Pem);
+
+ QFile keyFile(":/resources/server.key");
+ QVERIFY2(keyFile.open(QIODevice::ReadOnly), qPrintable(keyFile.errorString()));
+ const QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
+
+ HttpsServer server(":/resources/server.pem", ":/resources/server.key", ":/resources/ca.pem");
+ server.setExpectError(false);
+ QVERIFY(server.start());
+
+ connect(&server, &HttpsServer::newRequest, [](HttpReqRep *rr) {
+ rr->setResponseBody(QByteArrayLiteral("<html><body>TEST</body></html>"));
+ rr->sendResponse();
+ });
+
+ {
+ QWebEnginePage page;
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ page.profile()->clientCertificateStore()->add(cert, sslKey);
+
+ connect(&page, &QWebEnginePage::selectClientCertificate, &page,
+ [](QWebEngineClientCertificateSelection selection) {
+ Q_UNUSED(selection)
+ QFAIL("Should have rejected handshake already.");
+ });
+
+ QSignalSpy certificateErrorSpy(&page, &QWebEnginePage::certificateError);
+ page.setUrl(server.url());
+
+ QTRY_COMPARE_WITH_TIMEOUT(certificateErrorSpy.size() > 0, true, 20000);
+
+ auto error = certificateErrorSpy.takeFirst().at(0).value<QWebEngineCertificateError>();
+ QCOMPARE(error.type(), QWebEngineCertificateError::CertificateAuthorityInvalid);
+ }
+
+ // Add the appropriate server certificate, connection should work then.
+
+ QList<QSslCertificate> certs;
+
+ for (QString filename : {":/resources/server.pem", ":/resources/ca.pem"}) {
+ QFile file(filename);
+ QVERIFY2(file.open(QIODevice::ReadOnly), qPrintable(file.errorString()));
+ certs.emplace_back(&file, QSsl::Pem);
+ QVERIFY(!certs.back().isNull());
+ }
+
+ QWebEngineProfileBuilder profileBuilder;
+ profileBuilder.setAdditionalTrustedCertificates(certs);
+ QScopedPointer<QWebEngineProfile> profile(profileBuilder.createProfile(QStringLiteral("Test")));
+ QVERIFY(profile);
+
+ QCOMPARE(profile->additionalTrustedCertificates(), certs);
+
+ {
+ QWebEnginePage page(profile.get());
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ page.profile()->clientCertificateStore()->add(cert, sslKey);
+
+ connect(&page, &QWebEnginePage::selectClientCertificate, &page,
+ [&cert](QWebEngineClientCertificateSelection selection) {
+ QVERIFY(!selection.certificates().isEmpty());
+ for (const QSslCertificate &sCert : selection.certificates()) {
+ if (cert == sCert) {
+ selection.select(sCert);
+ return;
+ }
+ }
+ QFAIL("No certificate found.");
+ });
+
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ page.setUrl(server.url());
+
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size() > 0, true, 20000);
+ QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("TEST"));
+ }
+
+ QVERIFY(server.stop());
+}
+
void tst_QWebEngineProfileBuilder::useSameDataPathForProfiles()
{
QWebEngineProfileBuilder profileBuilder;