summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/api/core_api.pro1
-rw-r--r--src/core/api/qwebengineclientcertificatestore.h77
-rw-r--r--src/core/client_cert_override_key.cpp137
-rw-r--r--src/core/client_cert_override_key_p.h52
-rw-r--r--src/core/client_cert_override_p.h63
-rw-r--r--src/core/content_browser_client_qt.cpp26
-rw-r--r--src/core/core_chromium.pri4
-rw-r--r--src/core/qtwebengine.gni1
-rw-r--r--src/core/qwebengineclientcertificatestore.cpp282
9 files changed, 620 insertions, 23 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 38dc6b39d..b5bb93847 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -32,6 +32,7 @@ gcc: QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter
HEADERS = \
qwebenginecallback.h \
qwebenginecallback_p.h \
+ qwebengineclientcertificatestore.h \
qtwebenginecoreglobal.h \
qtwebenginecoreglobal_p.h \
qwebenginecookiestore.h \
diff --git a/src/core/api/qwebengineclientcertificatestore.h b/src/core/api/qwebengineclientcertificatestore.h
new file mode 100644
index 000000000..82607ea70
--- /dev/null
+++ b/src/core/api/qwebengineclientcertificatestore.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** 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 QWEBENGINECLIENTCERTIFICATESTORE_H
+#define QWEBENGINECLIENTCERTIFICATESTORE_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtNetwork/qsslcertificate.h>
+#include <QtNetwork/qsslkey.h>
+
+QT_BEGIN_NAMESPACE
+
+struct QWebEngineClientCertificateStoreData;
+
+class QWEBENGINECORE_EXPORT QWebEngineClientCertificateStore {
+
+public:
+ struct Entry {
+ QSslKey privateKey;
+ QSslCertificate certificate;
+ };
+
+ static QWebEngineClientCertificateStore *getInstance();
+ void add(const QSslCertificate &certificate, const QSslKey &privateKey);
+ QList<Entry> toList() const;
+ void remove(Entry entry);
+ void clear();
+
+private:
+ static QWebEngineClientCertificateStore *m_instance;
+ Q_DISABLE_COPY(QWebEngineClientCertificateStore)
+
+ QWebEngineClientCertificateStore();
+ ~QWebEngineClientCertificateStore();
+ QWebEngineClientCertificateStoreData *d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWebEngineClientCertificateStore_H
diff --git a/src/core/client_cert_override_key.cpp b/src/core/client_cert_override_key.cpp
new file mode 100644
index 000000000..99ddf7466
--- /dev/null
+++ b/src/core/client_cert_override_key.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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 CLIENT_CERT_OVERRIDE_KEY_H
+#define CLIENT_CERT_OVERRIDE_KEY_H
+
+#include "client_cert_override_key_p.h"
+
+#include "third_party/boringssl/src/include/openssl/ssl.h"
+#include "third_party/boringssl/src/include/openssl/digest.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/rsa.h"
+#include "third_party/boringssl/src/include/openssl/pem.h"
+
+#include <utility>
+#include <QByteArray>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "net/base/net_errors.h"
+#include "net/ssl/ssl_platform_key_util.h"
+#include "net/ssl/ssl_private_key.h"
+#include "net/ssl/threaded_ssl_private_key.h"
+
+namespace net {
+
+namespace {
+
+class SSLPlatformKeyOverride : public ThreadedSSLPrivateKey::Delegate {
+public:
+ SSLPlatformKeyOverride(const QByteArray &sslKeyInBytes)
+ {
+ mem_ = BIO_new_mem_buf(sslKeyInBytes, -1);
+ key_ = PEM_read_bio_PrivateKey(mem_, NULL, 0, NULL);
+ }
+
+ ~SSLPlatformKeyOverride() override {
+ if (key_)
+ EVP_PKEY_free(key_);
+ if (mem_)
+ BIO_free(mem_);
+ }
+
+ Error Sign(uint16_t algorithm,
+ base::span<const uint8_t> input,
+ std::vector<uint8_t>* signature) override {
+ bssl::ScopedEVP_MD_CTX ctx;
+ EVP_PKEY_CTX* pctx;
+ if (!EVP_DigestSignInit(ctx.get(), &pctx,
+ SSL_get_signature_algorithm_digest(algorithm),
+ nullptr, key_)) {
+ return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
+
+ if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
+ if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* hash length */)) {
+ return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
+ }
+ size_t sig_len = 0;
+ if (!EVP_DigestSign(ctx.get(), NULL, &sig_len, input.data(), input.size()))
+ return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ signature->resize(sig_len);
+ if (!EVP_DigestSign(ctx.get(), signature->data(), &sig_len, input.data(),
+ input.size())) {
+ return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
+ }
+ signature->resize(sig_len);
+ return OK;
+ }
+
+ std::vector<uint16_t> GetAlgorithmPreferences() override {
+ return {
+ SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512,
+ SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256,
+ };
+ }
+
+private:
+ EVP_PKEY* key_;
+ BIO * mem_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyOverride);
+};
+
+} // namespace
+
+scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes) {
+ if (sslKeyInBytes.isEmpty())
+ return nullptr;
+
+ return base::MakeRefCounted<ThreadedSSLPrivateKey>(
+ std::make_unique<SSLPlatformKeyOverride>(sslKeyInBytes),
+ GetSSLPlatformKeyTaskRunner());
+}
+
+} // namespace net
+
+#endif
diff --git a/src/core/client_cert_override_key_p.h b/src/core/client_cert_override_key_p.h
new file mode 100644
index 000000000..7ac610be4
--- /dev/null
+++ b/src/core/client_cert_override_key_p.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 CLIENT_CERT_OVERRIDE_KEY_P_H
+#define CLIENT_CERT_OVERRIDE_KEY_P_H
+
+#include "net/ssl/ssl_private_key.h"
+
+#include <QByteArray>
+
+namespace net {
+ class SSLPrivateKey;
+ scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(const QByteArray &sslKeyInBytes);
+} // namespace net
+
+#endif
diff --git a/src/core/client_cert_override_p.h b/src/core/client_cert_override_p.h
new file mode 100644
index 000000000..b222bf810
--- /dev/null
+++ b/src/core/client_cert_override_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 CLIENT_CERT_OVERRIDE_P_H
+#define CLIENT_CERT_OVERRIDE_P_H
+
+#include "net/ssl/client_cert_store.h"
+#include "base/callback_forward.h"
+#include "net/cert/x509_certificate.h"
+
+namespace net {
+class SSLCertRequestInfo;
+class ClientCertOverrideStore : public ClientCertStore
+{
+public:
+ ClientCertOverrideStore();
+ virtual ~ClientCertOverrideStore() override;
+ void GetClientCerts(const SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback) override;
+private:
+ std::unique_ptr<net::ClientCertStore> getNativeStore();
+};
+} // namespace net
+
+#endif
+
+
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index beec6dd26..b5b2ca0fd 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -85,6 +85,7 @@
#include "qtwebengine/grit/qt_webengine_resources.h"
+#include "client_cert_override_p.h"
#include "profile_adapter.h"
#include "browser_main_parts_qt.h"
#include "browser_message_filter_qt.h"
@@ -113,18 +114,6 @@
#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"
@@ -381,17 +370,8 @@ std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertSt
{
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
+
+ return std::unique_ptr<net::ClientCertStore>(new net::ClientCertOverrideStore());
}
std::string ContentBrowserClientQt::GetApplicationLocale()
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 0aa7fd567..65ca793f9 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -48,6 +48,7 @@ SOURCES = \
browser_message_filter_qt.cpp \
certificate_error_controller.cpp \
chromium_overrides.cpp \
+ client_cert_override_key.cpp \
client_cert_select_controller.cpp \
clipboard_qt.cpp \
color_chooser_qt.cpp \
@@ -102,6 +103,7 @@ SOURCES = \
profile_io_data_qt.cpp \
quota_permission_context_qt.cpp \
quota_request_controller_impl.cpp \
+ qwebengineclientcertificatestore.cpp \
register_protocol_handler_request_controller_impl.cpp \
render_view_context_menu_qt.cpp \
render_view_observer_host_qt.cpp \
@@ -141,6 +143,8 @@ HEADERS = \
certificate_error_controller_p.h \
certificate_error_controller.h \
chromium_overrides.h \
+ client_cert_override_key_p.h \
+ client_cert_override_p.h \
client_cert_select_controller.h \
clipboard_qt.h \
color_chooser_qt.h \
diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni
index 14da1e6cf..57dfbec40 100644
--- a/src/core/qtwebengine.gni
+++ b/src/core/qtwebengine.gni
@@ -9,6 +9,7 @@ chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("/
include_dirs = [
"//skia/config",
"//third_party",
+ "//third_party/boringssl/src/include",
"//third_party/skia/include/core"
]
diff --git a/src/core/qwebengineclientcertificatestore.cpp b/src/core/qwebengineclientcertificatestore.cpp
new file mode 100644
index 000000000..fb6cba78f
--- /dev/null
+++ b/src/core/qwebengineclientcertificatestore.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** 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 "api/qwebengineclientcertificatestore.h"
+#include "client_cert_override_key_p.h"
+#include "client_cert_override_p.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/callback_forward.h"
+
+#include "net/ssl/client_cert_store.h"
+#include "net/ssl/ssl_cert_request_info.h"
+#include "net/cert/x509_certificate.h"
+
+#include "third_party/boringssl/src/include/openssl/pem.h"
+#include "third_party/boringssl/src/include/openssl/err.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+
+#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
+
+#include <QByteArray>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+
+typedef struct OverrideData {
+ QSslKey key;
+ QSslCertificate certificate;
+ scoped_refptr<net::X509Certificate> certPtr;
+ scoped_refptr<net::SSLPrivateKey> keyPtr;
+} OverrideData;
+
+struct QWebEngineClientCertificateStoreData {
+ QList<OverrideData*> deletedCerts;
+};
+
+static QList<OverrideData*> ClientCertOverrideData;
+QWebEngineClientCertificateStore *QWebEngineClientCertificateStore::m_instance = NULL;
+
+/*!
+ \class QWebEngineClientCertificateStore::Entry
+ \inmodule QtWebEngineCore
+ \since 5.13
+ \brief This structure holds the certificate and the private key.
+*/
+
+/*!
+ \class QWebEngineClientCertificateStore
+ \inmodule QtWebEngineCore
+ \since 5.13
+ \brief The QWebEngineClientCertificateStore class provides an in-memory store for client certificates.
+
+ The class allows to store client certificates in an in-memory store.
+ When a web site requests an SSL client certificate, the QWebEnginePage::selectClientCertificate
+ signal is emitted with matching certificates from the native certificate store or the in-memory store.
+ The getInstance() method can be used to access the single instance of the class.
+*/
+
+QWebEngineClientCertificateStore::QWebEngineClientCertificateStore()
+{
+ this->d_ptr = new QWebEngineClientCertificateStoreData;
+}
+
+/*!
+ Destroys this QWebEngineClientCertificateStore object.
+*/
+
+QWebEngineClientCertificateStore::~QWebEngineClientCertificateStore()
+{
+ // Just in case user has not deleted in-memory certificates
+ clear();
+
+ qDeleteAll(d_ptr->deletedCerts);
+ delete d_ptr;
+}
+
+/*!
+ 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)
+{
+
+ QByteArray sslKeyInBytes = privateKey.toPem();
+ QByteArray certInBytes = certificate.toDer();
+
+ OverrideData* data = new OverrideData;
+ data->keyPtr = net::WrapOpenSSLPrivateKey(sslKeyInBytes);
+ data->certPtr = net::X509Certificate::CreateFromBytes(
+ certInBytes.data(), certInBytes.length());
+ data->key = privateKey;
+ data->certificate = certificate;
+ ClientCertOverrideData.append(data);
+}
+
+/*!
+ Returns a list of private and public keys of client certificates in the in-memory store.
+ Returns an empty list if the in-memory store does not contain certificates.
+*/
+
+QList<QWebEngineClientCertificateStore::Entry> QWebEngineClientCertificateStore::toList() const
+{
+ QList<Entry> certificateList;
+ for (auto data : ClientCertOverrideData) {
+ Entry entry;
+ entry.certificate = data->certificate;
+ entry.privateKey = data->key;
+ certificateList.append(entry);
+ }
+ return certificateList;
+}
+
+/*!
+ Deletes all the instances of the client certificate in the in-memory client certificate store
+ that matches the certificate in the \a entry.
+*/
+
+void QWebEngineClientCertificateStore::remove(Entry entry)
+{
+ QMutableListIterator<OverrideData*> iterator(ClientCertOverrideData);
+ while (iterator.hasNext()) {
+ auto overrideData = iterator.next();
+ if (entry.certificate.toDer() == overrideData->certificate.toDer()) {
+ d_ptr->deletedCerts.append(overrideData);
+ iterator.remove();
+ }
+ }
+}
+
+/*!
+ Clears all the client certificates from the in-memory store.
+*/
+
+void QWebEngineClientCertificateStore::clear()
+{
+ for (auto data : ClientCertOverrideData)
+ d_ptr->deletedCerts.append(data);
+ ClientCertOverrideData.clear();
+}
+
+QT_END_NAMESPACE
+
+namespace net {
+
+namespace {
+
+class ClientCertIdentityOverride : public ClientCertIdentity {
+public:
+ ClientCertIdentityOverride(
+ scoped_refptr<net::X509Certificate> cert,
+ scoped_refptr<net::SSLPrivateKey> key)
+ : ClientCertIdentity(std::move(cert)),
+ key_(std::move(key)) {}
+ ~ClientCertIdentityOverride() override = default;
+
+ void AcquirePrivateKey(
+ const base::Callback<void(scoped_refptr<SSLPrivateKey>)>&
+ private_key_callback) override
+ {
+ private_key_callback.Run(key_);
+ }
+
+#if defined(OS_MACOSX)
+ SecIdentityRef sec_identity_ref() const override
+ {
+ return nullptr;
+ }
+#endif
+
+private:
+ scoped_refptr<net::SSLPrivateKey> key_;
+};
+
+} // namespace
+
+
+ClientCertOverrideStore::ClientCertOverrideStore()
+ : ClientCertStore()
+{
+}
+
+ClientCertOverrideStore::~ClientCertOverrideStore()
+{
+}
+
+void ClientCertOverrideStore::GetClientCerts(const SSLCertRequestInfo &cert_request_info,
+ const ClientCertListCallback &callback)
+{
+ // Look for certificates in memory store
+ for (int i = 0; i < ClientCertOverrideData.length(); i++) {
+ scoped_refptr<net::X509Certificate> cert = ClientCertOverrideData[i]->certPtr;
+ if (cert != NULL && cert->IsIssuedByEncoded(cert_request_info.cert_authorities)) {
+ ClientCertIdentityList selected_identities;
+ selected_identities.push_back(std::make_unique<ClientCertIdentityOverride>(cert, ClientCertOverrideData[i]->keyPtr));
+ callback.Run(std::move(selected_identities));
+ return;
+ }
+ }
+
+ // Continue with native cert store if matching certificate is not found in memory
+ std::unique_ptr<net::ClientCertStore> store = getNativeStore();
+ if (store != NULL) {
+ store->GetClientCerts(cert_request_info, callback);
+ return;
+ }
+
+ callback.Run(ClientCertIdentityList());
+ return;
+}
+
+std::unique_ptr<net::ClientCertStore> ClientCertOverrideStore::getNativeStore()
+{
+#if defined(USE_NSS_CERTS)
+ 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
+}
+}