diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-06-21 12:16:00 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-07-08 19:23:08 +0000 |
commit | 10877c3ec0184e6c2a07b8775d32c8efc38a29a3 (patch) | |
tree | e5e1c69e2008205b2178c940c47c1349d6e41c7b | |
parent | a83fd13f62673ce439bdfea55238f9d8ef8676ce (diff) |
Enable client certificate store
Creates the default client cerficate store for the platform and when
given a choice of client certificates forwards to the choice to
the application.
Only a Widgets API for now.
Task-number: QTBUG-54877
Change-Id: Ie15152398d5769579fa0c07e3e3035c2374e9940
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r-- | examples/webenginewidgets/simplebrowser/webpage.cpp | 8 | ||||
-rw-r--r-- | examples/webenginewidgets/simplebrowser/webpage.h | 1 | ||||
-rw-r--r-- | src/core/client_cert_select_controller.cpp | 123 | ||||
-rw-r--r-- | src/core/client_cert_select_controller.h | 99 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.cpp | 47 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.h | 1 | ||||
-rw-r--r-- | src/core/core_chromium.pri | 2 | ||||
-rw-r--r-- | src/core/web_contents_adapter_client.h | 2 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.cpp | 5 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.h | 4 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 5 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 1 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineclientcertselection.cpp | 123 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineclientcertselection.h | 80 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 31 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.h | 7 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage_p.h | 1 | ||||
-rw-r--r-- | src/webenginewidgets/webenginewidgets.pro | 2 |
18 files changed, 536 insertions, 6 deletions
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp index fcbb38b8f..353361e4d 100644 --- a/examples/webenginewidgets/simplebrowser/webpage.cpp +++ b/examples/webenginewidgets/simplebrowser/webpage.cpp @@ -57,6 +57,7 @@ #include <QAuthenticator> #include <QMessageBox> #include <QStyle> +#include <QWebEngineCertificateError> WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) : QWebEnginePage(profile, parent) @@ -65,6 +66,7 @@ WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::handleFeaturePermissionRequested); connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired); connect(this, &QWebEnginePage::registerProtocolHandlerRequested, this, &WebPage::handleRegisterProtocolHandlerRequested); + connect(this, &QWebEnginePage::selectClientCertificate, this, &WebPage::handleSelectClientCertificate); } bool WebPage::certificateError(const QWebEngineCertificateError &error) @@ -192,3 +194,9 @@ void WebPage::handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolH request.reject(); } //! [registerProtocolHandlerRequested] + +void WebPage::handleSelectClientCertificate(QWebEngineClientCertSelection selection) +{ + // Just select one. + selection.select(selection.certificates().at(0)); +} diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h index 0b9ef2abe..9c33d82df 100644 --- a/examples/webenginewidgets/simplebrowser/webpage.h +++ b/examples/webenginewidgets/simplebrowser/webpage.h @@ -69,6 +69,7 @@ private slots: void handleFeaturePermissionRequested(const QUrl &securityOrigin, Feature feature); void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth, const QString &proxyHost); void handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request); + void handleSelectClientCertificate(QWebEngineClientCertSelection clientCertSelection); }; #endif // WEBPAGE_H diff --git a/src/core/client_cert_select_controller.cpp b/src/core/client_cert_select_controller.cpp new file mode 100644 index 000000000..16d23454f --- /dev/null +++ b/src/core/client_cert_select_controller.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "client_cert_select_controller.h" + +#include <base/bind.h> +#include <content/public/browser/client_certificate_delegate.h> +#include <net/cert/x509_certificate.h> +#include <net/ssl/client_cert_identity.h> +#include <net/ssl/ssl_cert_request_info.h> +#include <net/ssl/ssl_info.h> + +#include "type_conversion.h" + +QT_BEGIN_NAMESPACE + +using namespace QtWebEngineCore; + +ClientCertSelectController::ClientCertSelectController(net::SSLCertRequestInfo *certRequestInfo, + std::vector<std::unique_ptr<net::ClientCertIdentity>> clientCerts, + std::unique_ptr<content::ClientCertificateDelegate> delegate) + : m_clientCerts(std::move(clientCerts)) + , m_delegate(std::move(delegate)) + , m_selected(false) +{ + m_hostAndPort.setHost(QString::fromStdString(certRequestInfo->host_and_port.HostForURL())); + m_hostAndPort.setPort(certRequestInfo->host_and_port.port()); +} + +ClientCertSelectController::~ClientCertSelectController() +{ + // Continue without a client certificate, for instance if the app has not + // implemented support for client certificate selection. + if (!m_selected) + m_delegate->ContinueWithCertificate(nullptr, nullptr); +} + +#if QT_CONFIG(ssl) + +void ClientCertSelectController::selectNone() +{ + if (m_selected) { + qWarning() << "ClientCertSelectController::selectNone() certicate already selected"; + return; + } + m_selected = true; + m_delegate->ContinueWithCertificate(nullptr, nullptr); +} + +void ClientCertSelectController::select(const QSslCertificate &certificate) +{ + if (m_selected) { + qWarning() << "ClientCertSelectController::select() certicate already selected"; + return; + } + QByteArray derCertificate = certificate.toDer(); + scoped_refptr<net::X509Certificate> selectedCert = + net::X509Certificate::CreateFromBytes(derCertificate.constData(), derCertificate.length()); + for (auto &certInfo : m_clientCerts) { + scoped_refptr<net::X509Certificate> cert = certInfo->certificate(); + if (cert->Equals(selectedCert.get())) { + m_selected = true; + net::ClientCertIdentity::SelfOwningAcquirePrivateKey( + std::move(certInfo), + base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate, + base::Passed(std::move(m_delegate)), std::move(cert))); + return; + } + } + qWarning() << "ClientCertSelectController::select() - selected client certificate not recognized." + << " Selected certificate needs to be one of the offered"; +} + +QVector<QSslCertificate> ClientCertSelectController::certificates() const +{ + QVector<QSslCertificate> out; + for (auto &cert : m_clientCerts) { + std::vector<std::string> pem_encoded; + if (cert->certificate()->GetPEMEncodedChain(&pem_encoded)) + out.append(QSslCertificate(QByteArray::fromStdString(pem_encoded.front()))); + } + return out; +} + +#endif // QT_CONFIG(ssl) + +QT_END_NAMESPACE diff --git a/src/core/client_cert_select_controller.h b/src/core/client_cert_select_controller.h new file mode 100644 index 000000000..4a245c74c --- /dev/null +++ b/src/core/client_cert_select_controller.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef CLIENT_CERT_SELECT_CONTROLLER_H +#define CLIENT_CERT_SELECT_CONTROLLER_H + +#include "qtwebenginecoreglobal_p.h" +#include <QtNetwork/qtnetwork-config.h> + +#include <QtCore/QUrl> +#if QT_CONFIG(ssl) +#include <QtCore/QVector> +#include <QtNetwork/QSslCertificate> +#endif +#include <memory> + +namespace content { +class ClientCertificateDelegate; +} + +namespace net { +class ClientCertIdentity; +class SSLCertRequestInfo; +} + +QT_BEGIN_NAMESPACE + +class QWEBENGINECORE_PRIVATE_EXPORT ClientCertSelectController { +public: + ClientCertSelectController(net::SSLCertRequestInfo *certRequestInfo, + std::vector<std::unique_ptr<net::ClientCertIdentity>> clientCerts, + std::unique_ptr<content::ClientCertificateDelegate> delegate); + ~ClientCertSelectController(); + + QUrl hostAndPort() const { return m_hostAndPort; } +#if QT_CONFIG(ssl) + void selectNone(); + void select(const QSslCertificate &certificate); + + QVector<QSslCertificate> certificates() const; +#endif // QT_CONFIG(ssl) + +private: + QUrl m_hostAndPort; + std::vector<std::unique_ptr<net::ClientCertIdentity>> m_clientCerts; + std::unique_ptr<content::ClientCertificateDelegate> m_delegate; + bool m_selected; +}; + +QT_END_NAMESPACE + +#endif // CLIENT_CERT_SELECT_CONTROLLER_H diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 3566cae51..7bbe85b4e 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -93,6 +93,7 @@ #include "browser_message_filter_qt.h" #include "certificate_error_controller.h" #include "certificate_error_controller_p.h" +#include "client_cert_select_controller.h" #include "desktop_screen_qt.h" #include "devtools_manager_delegate_qt.h" #include "login_delegate_qt.h" @@ -120,6 +121,18 @@ #include "ui/base/resource/resource_bundle.h" #endif +#if defined(USE_NSS_CERTS) +#include "net/ssl/client_cert_store_nss.h" +#endif + +#if defined(OS_WIN) +#include "net/ssl/client_cert_store_win.h" +#endif + +#if defined(OS_MACOSX) +#include "net/ssl/client_cert_store_mac.h" +#endif + #if QT_CONFIG(webengine_pepper_plugins) #include "content/public/browser/browser_ppapi_host.h" #include "ppapi/host/ppapi_host.h" @@ -508,12 +521,38 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont contentsDelegate->allowCertificateError(errorController); } -void ContentBrowserClientQt::SelectClientCertificate(content::WebContents * /*webContents*/, - net::SSLCertRequestInfo * /*certRequestInfo*/, - net::ClientCertIdentityList /*client_certs*/, +void ContentBrowserClientQt::SelectClientCertificate(content::WebContents *webContents, + net::SSLCertRequestInfo *certRequestInfo, + net::ClientCertIdentityList clientCerts, std::unique_ptr<content::ClientCertificateDelegate> delegate) { - delegate->ContinueWithCertificate(nullptr, nullptr); + if (!clientCerts.empty()) { + WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate()); + + QSharedPointer<ClientCertSelectController> certSelectController( + new ClientCertSelectController(certRequestInfo, std::move(clientCerts), std::move(delegate))); + + contentsDelegate->selectClientCert(certSelectController); + } else { + delegate->ContinueWithCertificate(nullptr, nullptr); + } +} + +std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertStore(content::ResourceContext *resource_context) +{ + if (!resource_context) + return nullptr; +#if defined(USE_NSS_CERTS) + // FIXME: Give it a proper callback for a password delegate. + return std::unique_ptr<net::ClientCertStore>( + new net::ClientCertStoreNSS(net::ClientCertStoreNSS::PasswordDelegateFactory())); +#elif defined(OS_WIN) + return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin()); +#elif defined(OS_MACOSX) + return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac()); +#else + return nullptr; +#endif } std::string ContentBrowserClientQt::GetApplicationLocale() diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 6956bc736..5a3fafd1a 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -106,6 +106,7 @@ public: net::SSLCertRequestInfo* cert_request_info, net::ClientCertIdentityList client_certs, std::unique_ptr<content::ClientCertificateDelegate> delegate) override; + std::unique_ptr<net::ClientCertStore> CreateClientCertStore(content::ResourceContext *resource_context) override; content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override; std::string GetApplicationLocale() override; diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 0b1eba5dd..6c4bfc0e1 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -48,6 +48,7 @@ SOURCES = \ certificate_error_controller.cpp \ chromium_gpu_helper.cpp \ chromium_overrides.cpp \ + client_cert_select_controller.cpp \ clipboard_qt.cpp \ color_chooser_qt.cpp \ color_chooser_controller.cpp \ @@ -136,6 +137,7 @@ HEADERS = \ certificate_error_controller_p.h \ certificate_error_controller.h \ chromium_overrides.h \ + client_cert_select_controller.h \ clipboard_qt.h \ color_chooser_qt.h \ color_chooser_controller_p.h \ diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 177591772..c539bfa66 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -61,6 +61,7 @@ #include <QUrl> QT_FORWARD_DECLARE_CLASS(CertificateErrorController) +QT_FORWARD_DECLARE_CLASS(ClientCertSelectController) QT_FORWARD_DECLARE_CLASS(QKeyEvent) QT_FORWARD_DECLARE_CLASS(QVariant) QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest) @@ -456,6 +457,7 @@ public: virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0; virtual void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) = 0; virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0; + virtual void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) = 0; virtual void updateScrollPosition(const QPointF &position) = 0; virtual void updateContentsSize(const QSizeF &size) = 0; virtual void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 8afb7ea70..8abe2263d 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -558,6 +558,11 @@ void WebContentsDelegateQt::allowCertificateError(const QSharedPointer<Certifica m_viewClient->allowCertificateError(errorController); } +void WebContentsDelegateQt::selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) +{ + m_viewClient->selectClientCert(selectController); +} + void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingOrigin) { m_viewClient->runGeolocationPermissionRequest(requestingOrigin); diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index b120ec95a..b2ca4e491 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -53,6 +53,7 @@ #include <QtCore/qvector.h> QT_FORWARD_DECLARE_CLASS(CertificateErrorController) +QT_FORWARD_DECLARE_CLASS(ClientCertSelectController) namespace content { class BrowserContext; @@ -142,7 +143,8 @@ public: void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription); void overrideWebPreferences(content::WebContents *, content::WebPreferences*); - void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ; + void allowCertificateError(const QSharedPointer<CertificateErrorController> &); + void selectClientCert(const QSharedPointer<ClientCertSelectController> &); void requestGeolocationPermission(const QUrl &requestingOrigin); void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture); FaviconManager *faviconManager(); diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 7e5897157..c19c731a8 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -269,6 +269,11 @@ void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<Cert m_certificateErrorControllers.append(errorController); } +void QQuickWebEngineViewPrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &) +{ + // Doing nothing will free the select-controller and perform default continue. +} + void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url) { Q_Q(QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 7a196bd70..0e48ffc94 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -139,6 +139,7 @@ public: QObject *accessibilityParentObject() override; QtWebEngineCore::WebEngineSettings *webEngineSettings() const override; void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) override; + void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) override; void runGeolocationPermissionRequest(QUrl const&) override; void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override; void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override; diff --git a/src/webenginewidgets/api/qwebengineclientcertselection.cpp b/src/webenginewidgets/api/qwebengineclientcertselection.cpp new file mode 100644 index 000000000..de1e101f6 --- /dev/null +++ b/src/webenginewidgets/api/qwebengineclientcertselection.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwebengineclientcertselection.h" + +#if QT_CONFIG(ssl) + +#include "client_cert_select_controller.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QWebEngineClientCertSelection + \brief The QWebEngineClientCertSelection class wraps a client certificate selection. + \since 5.12 + \inmodule QtWebEngineWidgets + + Provides access to the certicates to choose from, and a method for selecting one. + + The selection is asynchronous. If no certificate is selected and no copy of the + object is kept alive, loading will continue without a certificate. +*/ + +/*! \internal +*/ +QWebEngineClientCertSelection::QWebEngineClientCertSelection(QSharedPointer<ClientCertSelectController> selectController) + : d_ptr(selectController) +{} + +QWebEngineClientCertSelection::QWebEngineClientCertSelection(const QWebEngineClientCertSelection &other) + : d_ptr(other.d_ptr) +{} + +QWebEngineClientCertSelection &QWebEngineClientCertSelection::operator=(const QWebEngineClientCertSelection &other) +{ + d_ptr = other.d_ptr; + return *this; +} + +QWebEngineClientCertSelection::~QWebEngineClientCertSelection() +{ +} + +/*! + Returns the client certificates available to choose from. + + \sa select() +*/ +QVector<QSslCertificate> QWebEngineClientCertSelection::certificates() const +{ + return d_ptr->certificates(); +} + +/*! + Selects the client certificate \a certificate. The certificate must be one + of those offered in certificates(). + + \sa certificates(), selectNone() +*/ +void QWebEngineClientCertSelection::select(const QSslCertificate &certificate) +{ + d_ptr->select(certificate); +} + +/*! + Continue without using any of the offered certificates. This is the same + action as taken when destroying the last copy of this object if no + selection has been made. + + \sa select() +*/ +void QWebEngineClientCertSelection::selectNone() +{ + d_ptr->selectNone(); +} + +/*! + Returns the host and port of the server requesting the client certificate. +*/ +QUrl QWebEngineClientCertSelection::host() const +{ + return d_ptr->hostAndPort(); +} + +QT_END_NAMESPACE + +#endif // QT_CONFIG(ssl) diff --git a/src/webenginewidgets/api/qwebengineclientcertselection.h b/src/webenginewidgets/api/qwebengineclientcertselection.h new file mode 100644 index 000000000..84de56a67 --- /dev/null +++ b/src/webenginewidgets/api/qwebengineclientcertselection.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECLIENTCERTSELECTION_H +#define QWEBENGINECLIENTCERTSELECTION_H + +#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> +#include <QtNetwork/qtnetwork-config.h> + +#if QT_CONFIG(ssl) + +#include <QtCore/QScopedPointer> +#include <QtCore/QVector> +#include <QtNetwork/QSslCertificate> + +QT_BEGIN_NAMESPACE +class ClientCertSelectController; + +class QWEBENGINEWIDGETS_EXPORT QWebEngineClientCertSelection { +public: + QWebEngineClientCertSelection(const QWebEngineClientCertSelection &); + ~QWebEngineClientCertSelection(); + + QWebEngineClientCertSelection &operator=(const QWebEngineClientCertSelection &); + + QUrl host() const; + + void select(const QSslCertificate &certificate); + void selectNone(); + QVector<QSslCertificate> certificates() const; + +private: + friend class QWebEnginePagePrivate; + + QWebEngineClientCertSelection(QSharedPointer<ClientCertSelectController>); + + QSharedPointer<ClientCertSelectController> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QT_CONFIG(ssl) + +#endif // QWEBENGINECLIENTCERTSELECTION_H diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 2bb19361a..885ad7a69 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -50,6 +50,7 @@ #if QT_CONFIG(webengine_printing_and_pdf) #include "printing/pdfium_document_wrapper_qt.h" #endif +#include "qwebenginecertificateerror.h" #include "qwebenginefullscreenrequest.h" #include "qwebenginehistory.h" #include "qwebenginehistory_p.h" @@ -1632,6 +1633,36 @@ void QWebEnginePagePrivate::allowCertificateError(const QSharedPointer<Certifica controller->accept(accepted); } +void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller) +{ +#if QT_CONFIG(ssl) + Q_Q(QWebEnginePage); + QWebEngineClientCertSelection certSelection(controller); + + Q_EMIT q->selectClientCertificate(certSelection); +#else + Q_UNUSED(controller); +#endif +} + +#if QT_CONFIG(ssl) +/*! + \fn void QWebEnginePage::selectClientCertificate(QWebEngineClientCertSelection clientCertSelection) + \since 5.12 + + This signal is emitted when a web site requests an SSL client certificate, and one or more were + found in system's client certificate store. + + Handling the signal is asynchronous, and loading will be waiting until a certificate is selected, + or the last copy of \a clientCertSelection is destroyed. + + If the signal is not handled, \a clientCertSelection is automatically destroyed, and loading + will continue without a client certificate. + + \sa QWebEngineClientCertSelection +*/ +#endif + void QWebEnginePagePrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) { Q_Q(QWebEnginePage); diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index 3edfb96d0..6de31d9d5 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -41,7 +41,7 @@ #define QWEBENGINEPAGE_H #include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h> -#include <QtWebEngineWidgets/qwebenginecertificateerror.h> +#include <QtWebEngineWidgets/qwebengineclientcertselection.h> #include <QtWebEngineWidgets/qwebenginedownloaditem.h> #include <QtWebEngineCore/qwebenginecallback.h> #include <QtWebEngineCore/qwebenginehttprequest.h> @@ -59,6 +59,8 @@ class QPrinter; class QContextMenuBuilder; class QWebChannel; +class QWebEngineCertificateError; +class QWebEngineClientCertSelection; class QWebEngineContextMenuData; class QWebEngineFullScreenRequest; class QWebEngineHistory; @@ -318,6 +320,9 @@ Q_SIGNALS: void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest); void quotaRequested(QWebEngineQuotaRequest quotaRequest); void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request); +#if QT_CONFIG(ssl) + void selectClientCertificate(QWebEngineClientCertSelection clientCertSelection); +#endif void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator); void proxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 831879127..e5657c1b6 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -136,6 +136,7 @@ public: QObject *accessibilityParentObject() override; QtWebEngineCore::WebEngineSettings *webEngineSettings() const override; void allowCertificateError(const QSharedPointer<CertificateErrorController> &controller) override; + void selectClientCert(const QSharedPointer<ClientCertSelectController> &controller) override; void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override; void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override; void updateScrollPosition(const QPointF &position) override; diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro index c96bf15bb..1e24f35e9 100644 --- a/src/webenginewidgets/webenginewidgets.pro +++ b/src/webenginewidgets/webenginewidgets.pro @@ -14,6 +14,7 @@ INCLUDEPATH += $$PWD api ../core ../core/api ../webengine/api SOURCES = \ api/qtwebenginewidgetsglobal.cpp \ api/qwebenginecertificateerror.cpp \ + api/qwebengineclientcertselection.cpp \ api/qwebenginecontextmenudata.cpp \ api/qwebenginedownloaditem.cpp \ api/qwebenginefullscreenrequest.cpp \ @@ -29,6 +30,7 @@ SOURCES = \ HEADERS = \ api/qtwebenginewidgetsglobal.h \ api/qwebenginecertificateerror.h \ + api/qwebengineclientcertselection.h \ api/qwebenginecontextmenudata.h \ api/qwebenginedownloaditem.h \ api/qwebenginedownloaditem_p.h \ |