summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-27 13:49:30 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-03-01 22:32:13 +0000
commit4dc312011bcaa2ee2cf812b5b84dc9238130e608 (patch)
tree495513b9fe73d2d1e45ea84c3e00e43e4625a5ee
parent9e299978cfb40e01f2871b71129a02f4b5b7404d (diff)
Tie client certificate stores to profiles
Move the client certificate store from being global to being tied to individual profiles. Change-Id: Ib21ae14c501b7d0612b84ae7535120291aeeada2 Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
-rw-r--r--src/core/api/qwebengineclientcertificatestore.cpp25
-rw-r--r--src/core/api/qwebengineclientcertificatestore.h12
-rw-r--r--src/core/net/client_cert_override.cpp15
-rw-r--r--src/core/net/client_cert_override.h6
-rw-r--r--src/core/profile_adapter.cpp8
-rw-r--r--src/core/profile_adapter.h4
-rw-r--r--src/core/profile_io_data_qt.cpp11
-rw-r--r--src/core/profile_io_data_qt.h3
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp11
-rw-r--r--src/webengine/api/qquickwebengineprofile.h3
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp11
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h3
-rw-r--r--tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp19
13 files changed, 85 insertions, 46 deletions
diff --git a/src/core/api/qwebengineclientcertificatestore.cpp b/src/core/api/qwebengineclientcertificatestore.cpp
index 40412dfd..cac8fb15 100644
--- a/src/core/api/qwebengineclientcertificatestore.cpp
+++ b/src/core/api/qwebengineclientcertificatestore.cpp
@@ -48,8 +48,6 @@ QT_BEGIN_NAMESPACE
#if QT_CONFIG(ssl)
-QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::m_instance = nullptr;
-
/*!
\class QWebEngineClientCertificateStore::Entry
\inmodule QtWebEngineCore
@@ -69,8 +67,8 @@ QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::m_instance =
The getInstance() method can be used to access the single instance of the class.
*/
-QWebEngineClientCertificateStore::QWebEngineClientCertificateStore()
- : d_ptr(new QtWebEngineCore::ClientCertificateStoreData)
+QWebEngineClientCertificateStore::QWebEngineClientCertificateStore(QtWebEngineCore::ClientCertificateStoreData *storeData)
+ : m_storeData(storeData)
{
}
@@ -85,23 +83,12 @@ QWebEngineClientCertificateStore::~QWebEngineClientCertificateStore()
}
/*!
- Returns an in-memory client certificate store.
-*/
-
-QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::getInstance()
-{
- if (!m_instance)
- m_instance = new QWebEngineClientCertificateStore;
- return m_instance;
-}
-
-/*!
Adds a \a certificate with the \a privateKey to the in-memory client certificate store.
*/
void QWebEngineClientCertificateStore::add(const QSslCertificate &certificate, const QSslKey &privateKey)
{
- d_ptr->add(certificate, privateKey);
+ m_storeData->add(certificate, privateKey);
}
/*!
@@ -112,7 +99,7 @@ void QWebEngineClientCertificateStore::add(const QSslCertificate &certificate, c
QList<QWebEngineClientCertificateStore::Entry> QWebEngineClientCertificateStore::toList() const
{
QList<Entry> certificateList;
- for (auto data : qAsConst(d_ptr->extraCerts)) {
+ for (auto data : qAsConst(m_storeData->extraCerts)) {
Entry entry;
entry.certificate = data->certificate;
entry.privateKey = data->key;
@@ -128,7 +115,7 @@ QList<QWebEngineClientCertificateStore::Entry> QWebEngineClientCertificateStore:
void QWebEngineClientCertificateStore::remove(const QSslCertificate &certificate)
{
- d_ptr->remove(certificate);
+ m_storeData->remove(certificate);
}
/*!
@@ -137,7 +124,7 @@ void QWebEngineClientCertificateStore::remove(const QSslCertificate &certificate
void QWebEngineClientCertificateStore::clear()
{
- d_ptr->clear();
+ m_storeData->clear();
}
#endif // QT_CONFIG(ssl)
diff --git a/src/core/api/qwebengineclientcertificatestore.h b/src/core/api/qwebengineclientcertificatestore.h
index 0000299a..441a5f91 100644
--- a/src/core/api/qwebengineclientcertificatestore.h
+++ b/src/core/api/qwebengineclientcertificatestore.h
@@ -47,15 +47,15 @@
#include <QtNetwork/qsslkey.h>
namespace QtWebEngineCore {
-class ClientCertOverrideStore;
struct ClientCertificateStoreData;
+class ProfileAdapter;
}
QT_BEGIN_NAMESPACE
#if QT_CONFIG(ssl)
-
+class QWebEngineProfile;
class QWEBENGINECORE_EXPORT QWebEngineClientCertificateStore {
public:
@@ -64,20 +64,18 @@ public:
QSslCertificate certificate;
};
- static QWebEngineClientCertificateStore *getInstance();
void add(const QSslCertificate &certificate, const QSslKey &privateKey);
QList<Entry> toList() const;
void remove(const QSslCertificate &certificate);
void clear();
private:
- friend class QtWebEngineCore::ClientCertOverrideStore;
- static QWebEngineClientCertificateStore *m_instance;
+ friend class QtWebEngineCore::ProfileAdapter;
Q_DISABLE_COPY(QWebEngineClientCertificateStore)
- QWebEngineClientCertificateStore();
+ QWebEngineClientCertificateStore(QtWebEngineCore::ClientCertificateStoreData *storeData);
~QWebEngineClientCertificateStore();
- QScopedPointer<QtWebEngineCore::ClientCertificateStoreData> d_ptr;
+ QtWebEngineCore::ClientCertificateStoreData *m_storeData;
};
#endif // QT_CONFIG(ssl)
diff --git a/src/core/net/client_cert_override.cpp b/src/core/net/client_cert_override.cpp
index cbcbb03b..305f0cef 100644
--- a/src/core/net/client_cert_override.cpp
+++ b/src/core/net/client_cert_override.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "net/client_cert_override.h"
+#include "client_cert_override.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -52,8 +52,7 @@
#include "third_party/boringssl/src/include/openssl/err.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
-#include "api/qwebengineclientcertificatestore.h"
-#include "net/client_cert_store_data.h"
+#include "client_cert_store_data.h"
#include "profile_io_data_qt.h"
#include <QtNetwork/qtnetworkglobal.h>
@@ -99,8 +98,9 @@ private:
namespace QtWebEngineCore {
-ClientCertOverrideStore::ClientCertOverrideStore()
+ClientCertOverrideStore::ClientCertOverrideStore(ClientCertificateStoreData *storeData)
: ClientCertStore()
+ , m_storeData(storeData)
, m_nativeStore(createNativeStore())
{
}
@@ -108,12 +108,10 @@ ClientCertOverrideStore::ClientCertOverrideStore()
ClientCertOverrideStore::~ClientCertOverrideStore() = default;
#if QT_CONFIG(ssl)
-// static
net::ClientCertIdentityList ClientCertOverrideStore::GetClientCertsOnUIThread(const net::SSLCertRequestInfo &cert_request_info)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- QWebEngineClientCertificateStore *clientCertificateStore = QWebEngineClientCertificateStore::getInstance();
- const auto &clientCertOverrideData = clientCertificateStore->d_ptr->extraCerts;
+ const auto &clientCertOverrideData = m_storeData->extraCerts;
// Look for certificates in memory store
for (int i = 0; i < clientCertOverrideData.length(); i++) {
scoped_refptr<net::X509Certificate> cert = clientCertOverrideData[i]->certPtr;
@@ -146,7 +144,8 @@ void ClientCertOverrideStore::GetClientCerts(const net::SSLCertRequestInfo &cert
// Access the user-provided data from the UI thread, but return on whatever thread this is.
if (base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, { content::BrowserThread::UI },
- base::BindOnce(&GetClientCertsOnUIThread, base::ConstRef(cert_request_info)),
+ base::BindOnce(&ClientCertOverrideStore::GetClientCertsOnUIThread,
+ base::Unretained(this), base::ConstRef(cert_request_info)),
base::BindOnce(&ClientCertOverrideStore::GetClientCertsReturn,
base::Unretained(this), base::ConstRef(cert_request_info), callback))
) {
diff --git a/src/core/net/client_cert_override.h b/src/core/net/client_cert_override.h
index 04c3ce66..35c1f96a 100644
--- a/src/core/net/client_cert_override.h
+++ b/src/core/net/client_cert_override.h
@@ -49,20 +49,22 @@ class SSLCertRequestInfo;
} // namespace net
namespace QtWebEngineCore {
+struct ClientCertificateStoreData;
class ClientCertOverrideStore : public net::ClientCertStore
{
public:
- ClientCertOverrideStore();
+ ClientCertOverrideStore(ClientCertificateStoreData *storeData);
virtual ~ClientCertOverrideStore() override;
void GetClientCerts(const net::SSLCertRequestInfo &cert_request_info,
const ClientCertListCallback &callback) override;
private:
static std::unique_ptr<net::ClientCertStore> createNativeStore();
- static net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
+ net::ClientCertIdentityList GetClientCertsOnUIThread(const net::SSLCertRequestInfo &request);
void GetClientCertsReturn(const net::SSLCertRequestInfo &cert_request_info,
const ClientCertListCallback &callback,
net::ClientCertIdentityList &&result);
+ ClientCertificateStoreData *m_storeData;
std::unique_ptr<net::ClientCertStore> m_nativeStore;
};
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 8ddeb5b8..4625d238 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -110,6 +110,7 @@ ProfileAdapter::~ProfileAdapter()
m_profile->GetDownloadManager(m_profile.data())->Shutdown();
m_downloadManagerDelegate.reset();
}
+ delete m_clientCertificateStore;
Q_ASSERT(m_pageRequestInterceptors == 0);
}
@@ -652,4 +653,11 @@ bool ProfileAdapter::isUsedForGlobalCertificateVerification() const
return m_usedForGlobalCertificateVerification;
}
+QWebEngineClientCertificateStore *ProfileAdapter::clientCertificateStore()
+{
+ if (!m_clientCertificateStore)
+ m_clientCertificateStore = new QWebEngineClientCertificateStore(m_profile->m_profileIOData->clientCertificateStoreData());
+ return m_clientCertificateStore;
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 48283501..480ca61f 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -60,6 +60,7 @@
#include <QString>
#include <QVector>
+#include "api/qwebengineclientcertificatestore.h"
#include "api/qwebenginecookiestore.h"
#include "api/qwebengineurlrequestinterceptor.h"
#include "api/qwebengineurlschemehandler.h"
@@ -200,6 +201,8 @@ public:
void removePageRequestInterceptor();
bool hasPageRequestInterceptor() const { return m_pageRequestInterceptors > 0; }
+ QWebEngineClientCertificateStore *clientCertificateStore();
+
QHash<QByteArray, QWeakPointer<UserNotificationController>> &ephemeralNotifications()
{ return m_ephemeralNotifications; }
QHash<QByteArray, QSharedPointer<UserNotificationController>> &persistentNotifications()
@@ -218,6 +221,7 @@ private:
QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate;
QScopedPointer<UserResourceControllerHost> m_userResourceController;
QScopedPointer<QWebEngineCookieStore> m_cookieStore;
+ QWebEngineClientCertificateStore *m_clientCertificateStore = nullptr;
QPointer<QWebEngineUrlRequestInterceptor> m_requestInterceptor;
QString m_dataPath;
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index 01a4e98a..f1fe96f8 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -79,6 +79,7 @@
#include "services/network/proxy_service_mojo.h"
#include "net/client_cert_override.h"
+#include "net/client_cert_store_data.h"
#include "net/cookie_monster_delegate_qt.h"
#include "net/custom_protocol_handler.h"
#include "net/network_delegate_qt.h"
@@ -168,6 +169,7 @@ static net::HttpNetworkSession::Params generateNetworkSessionParams(bool ignoreC
ProfileIODataQt::ProfileIODataQt(ProfileQt *profile)
: m_profile(profile),
+ m_clientCertificateStoreData(new ClientCertificateStoreData),
m_mutex(QMutex::Recursive),
m_weakPtrFactory(this)
{
@@ -207,6 +209,8 @@ QPointer<ProfileAdapter> ProfileIODataQt::profileAdapter()
void ProfileIODataQt::shutdownOnUIThread()
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ delete m_clientCertificateStoreData;
+ m_clientCertificateStoreData = nullptr;
bool posted = content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, this);
if (!posted) {
qWarning() << "Could not delete ProfileIODataQt on io thread !";
@@ -771,9 +775,14 @@ void ProfileIODataQt::updateUsedForGlobalCertificateVerification()
base::BindOnce(&ProfileIODataQt::setGlobalCertificateVerification, m_weakPtr));
}
+ClientCertificateStoreData *ProfileIODataQt::clientCertificateStoreData()
+{
+ return m_clientCertificateStoreData;
+}
+
std::unique_ptr<net::ClientCertStore> ProfileIODataQt::CreateClientCertStore()
{
- return std::unique_ptr<net::ClientCertStore>(new ClientCertOverrideStore());
+ return std::unique_ptr<net::ClientCertStore>(new ClientCertOverrideStore(m_clientCertificateStoreData));
}
// static
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index b983b3a9..edb2fd3b 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -69,6 +69,7 @@ class ExtensionSystemQt;
namespace QtWebEngineCore {
+class ClientCertificateStoreData;
class ProfileQt;
// ProfileIOData contains data that lives on the IOthread
@@ -123,6 +124,7 @@ public:
void updateUsedForGlobalCertificateVerification(); // runs on ui thread
bool hasPageInterceptors();
+ ClientCertificateStoreData *clientCertificateStoreData();
std::unique_ptr<net::ClientCertStore> CreateClientCertStore();
static ProfileIODataQt *FromResourceContext(content::ResourceContext *resource_context);
private:
@@ -146,6 +148,7 @@ private:
QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
QPointer<ProfileAdapter> m_profileAdapter; // never dereferenced in IO thread and it is passed by qpointer
ProfileAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy;
+ ClientCertificateStoreData *m_clientCertificateStoreData;
QString m_cookiesPath;
QString m_channelIdPath;
QString m_httpAcceptLanguage;
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 061e210f..0ec4b19c 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -1072,4 +1072,15 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineProfile::userScripts()
d->userScripts_clear);
}
+/*!
+ \since 5.13
+
+ Returns the profile's client certificate store.
+*/
+QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore()
+{
+ Q_D(QQuickWebEngineProfile);
+ return d->profileAdapter()->clientCertificateStore();
+}
+
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index 406d766f..e6f9fb73 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -54,6 +54,7 @@ class QQuickWebEngineDownloadItem;
class QQuickWebEngineProfilePrivate;
class QQuickWebEngineScript;
class QQuickWebEngineSettings;
+class QWebEngineClientCertificateStore;
class QWebEngineCookieStore;
class QWebEngineNotification;
class QWebEngineUrlRequestInterceptor;
@@ -153,6 +154,8 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ QWebEngineClientCertificateStore *clientCertificateStore();
+
static QQuickWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 5b4b540c..e183a66e 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -844,4 +844,15 @@ void QWebEngineProfile::clearHttpCache()
d->profileAdapter()->clearHttpCache();
}
+/*!
+ \since 5.13
+
+ Returns the profile's client certificate store.
+*/
+QWebEngineClientCertificateStore *QWebEngineProfile::clientCertificateStore()
+{
+ Q_D(QWebEngineProfile);
+ return d->profileAdapter()->clientCertificateStore();
+}
+
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index 6ffbd8a6..e3ddb594 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
class QObject;
class QUrl;
+class QWebEngineClientCertificateStore;
class QWebEngineCookieStore;
class QWebEngineDownloadItem;
class QWebEngineNotification;
@@ -142,6 +143,8 @@ public:
void setNotificationPresenter(std::function<void(const QWebEngineNotification &)> notificationPresenter);
+ QWebEngineClientCertificateStore *clientCertificateStore();
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
index fe2f7141..03e68c53 100644
--- a/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
+++ b/tests/auto/core/qwebengineclientcertificatestore/tst_qwebengineclientcertificatestore.cpp
@@ -28,6 +28,7 @@
#include <QtTest/QtTest>
#include <QtWebEngineCore/qwebengineclientcertificatestore.h>
+#include <QtWebEngineWidgets/qwebengineprofile.h>
class tst_QWebEngineClientCertificateStore : public QObject
{
@@ -73,24 +74,24 @@ void tst_QWebEngineClientCertificateStore::addAndListCertificates()
const QSslKey sslKeySecond(keyFileSecond.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "");
// Add certificates to in-memory store
- QWebEngineClientCertificateStore::getInstance()->add(cert, sslKey);
- QWebEngineClientCertificateStore::getInstance()->add(certSecond, sslKeySecond);
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(cert, sslKey);
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->add(certSecond, sslKeySecond);
- QCOMPARE(2, QWebEngineClientCertificateStore::getInstance()->toList().length());
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->toList().length());
}
void tst_QWebEngineClientCertificateStore::removeAndClearCertificates()
{
- QCOMPARE(2, QWebEngineClientCertificateStore::getInstance()->toList().length());
+ QCOMPARE(2, QWebEngineProfile::defaultProfile()->clientCertificateStore()->toList().length());
// Remove one certificate from in-memory store
- auto list = QWebEngineClientCertificateStore::getInstance()->toList();
- QWebEngineClientCertificateStore::getInstance()->remove(list[0].certificate);
- QCOMPARE(1, QWebEngineClientCertificateStore::getInstance()->toList().length());
+ auto list = QWebEngineProfile::defaultProfile()->clientCertificateStore()->toList();
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->remove(list[0].certificate);
+ QCOMPARE(1, QWebEngineProfile::defaultProfile()->clientCertificateStore()->toList().length());
// Remove all certificates in-memory store
- QWebEngineClientCertificateStore::getInstance()->clear();
- QCOMPARE(0, QWebEngineClientCertificateStore::getInstance()->toList().length());
+ QWebEngineProfile::defaultProfile()->clientCertificateStore()->clear();
+ QCOMPARE(0, QWebEngineProfile::defaultProfile()->clientCertificateStore()->toList().length());
}
QTEST_MAIN(tst_QWebEngineClientCertificateStore)